Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
20171209 Sakura ML Night
Search
ARIYAMA Keiji
December 09, 2017
Technology
0
150
20171209 Sakura ML Night
2017年12月9日に大阪で開催された「さくらの機械学習ナイト」の発表資料です。
「TensorFlowによるNSFW(職場で不適切な)画像検出」について。
ARIYAMA Keiji
December 09, 2017
Tweet
Share
More Decks by ARIYAMA Keiji
See All by ARIYAMA Keiji
Build with AI
keiji
0
220
DroidKaigi 2023
keiji
0
1.8k
TechFeed Conference 2022
keiji
0
280
Android Bazaar and Conference Diverse 2021 Winter
keiji
0
880
ci-cd-conference-2021
keiji
1
1.2k
Android Bazaar and Conference 2021 Spring
keiji
3
810
TFUG KANSAI 20190928
keiji
0
120
Softpia Japan Seminar 20190724
keiji
1
180
pixiv App Night 20190611
keiji
1
600
Other Decks in Technology
See All in Technology
dbt開発 with Claude Codeのためのガードレール設計
10xinc
2
1.3k
Modern Linux
oracle4engineer
PRO
0
160
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
8.8k
Apache Spark もくもく会
taka_aki
0
130
テストを軸にした生き残り術
kworkdev
PRO
0
210
Create Ruby native extension gem with Go
sue445
0
120
スマートファクトリーの第一歩 〜AWSマネージドサービスで 実現する予知保全と生成AI活用まで
ganota
2
310
新アイテムをどう使っていくか?みんなであーだこーだ言ってみよう / 20250911-rpi-jam-tokyo
akkiesoft
0
330
【NoMapsTECH 2025】AI Edge Computing Workshop
akit37
0
230
S3アクセス制御の設計ポイント
tommy0124
3
200
Automating Web Accessibility Testing with AI Agents
maminami373
0
1.3k
2つのフロントエンドと状態管理
mixi_engineers
PRO
3
120
Featured
See All Featured
Practical Orchestrator
shlominoach
190
11k
Designing for humans not robots
tammielis
253
25k
Done Done
chrislema
185
16k
The Cult of Friendly URLs
andyhume
79
6.6k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Gamification - CAS2011
davidbonilla
81
5.4k
The Art of Programming - Codeland 2020
erikaheidi
56
13k
Reflections from 52 weeks, 52 projects
jeffersonlam
352
21k
Being A Developer After 40
akosma
90
590k
How STYLIGHT went responsive
nonsquared
100
5.8k
Transcript
C-LIS CO., LTD.
C-LIS CO., LTD. ༗ࢁܓೋʢ,FJKJ"3*:"."ʣ $-*4$0 -5% "OESPJEΞϓϦ։ൃνϣοτσΩϧ Photo by
Koji MORIGUCHI (MORIGCHOWDER) ػցֶशͪΐͬͱͬͨ͜ͱ͋Γ·͢ Twitterͬͯ·ͤΜ
͘͞ΒͷػցֶशφΠτ 5FOTPS'MPXͰ /4'8ը૾ݕग़
5FOTPS'MPXʢ݄ൃදʣ ػցೳ͚ܭࢉϑϨʔϜϫʔΫ ࠷৽όʔδϣϯʢ݄ʣ
ษڧձΖ͏ͥ
(PPHMF%FWFMPQFS(SPVQ
IUUQTHEHLPCFEPPSLFFQFSKQFWFOUT
Πϯλʔωοτ͔Β Έͷը૾ΛࣗಈͰऩू͍ͨ͠
© ࠜઇΕ͍ ؟ ڸ ͬ ່
؟ڸ່ͬఆ 1 0
σʔληοτʢ݄࣌ʣ ؟ڸ່ͬɹຕ ඇ؟ڸ່ͬຕ ؟ڸ່ͬ ඇ؟ڸ່ͬ ޡݕग़ ؟ڸ່ͬ ඇ؟ڸ່ͬ
{ "generator": "Region Cropper", "file_name": "haruki_g17.png", "regions": [ { "probability":
1.0, "label": 2, "rect": { "left": 97.0, "top": 251.0, "right": 285.0, "bottom": 383.0 } }, { "probability": 1.0, "label": 2, "rect": { "left": 536.0, "top": 175.0, "right": 730.0, "bottom": 321.0 } } ] } Region Cropper: https://github.com/keiji/region_cropper
ߏ Downloader σʔληοτ Region + Label ઃఆ rsync
ཧͷߏ Downloader Face Detection Megane Detection ֬ೝɾमਖ਼ ೝࣝ݁Ռ ֶशʢ܇࿅ʣ
λΠϜϥΠϯ ϝσΟΞ σʔληοτ ֶशʢ܇࿅ʣ TensorFlow rsync
ઓͷաఔΛಉਓࢽʹ
͞·͟·ͳ՝ σʔληοτ͕(#Λ͑ͨ͋ͨΓ͔ΒϩʔΧϧͷಉظ͕ࠔʹɻ ྖҬʢ3FHJPOʣͷઃఆͱϥϕϧͷ༩૾Ҏ্ʹෛՙ͕ߴ͍ɻ
ը૾͕ສຕΛಥഁ σʔλཧ͕ࢸٸͷ՝ʹ
ඪΛ࠶֬ೝ
Πϯλʔωοτ͔Β Έͷ؟ڸ່ͬը૾ΛࣗಈͰऩू͍ͨ͠
Ҏલͷߏ Downloader σʔληοτ Region + Label ઃఆ rsync
ྖҬʴϥϕϧ
৽͍͠ߏ Downloader σʔληοτ Tagઃఆ
λά megane girl
؟ڸ່ͬผϞσϧ Ϟσϧ 1.00 0.00
%BUBTFU.BOBHFSGPS"OESPJE
σϞ
https://twitter.com/35s_00/status/930366666973757441
https://twitter.com/_meganeco
/4'8ʢ/PU4BGF'PS8PSLʣ
/4'8ը૾
͞·͟·ͳϦεΫ ࡞ۀͷϊΠζ ਫ਼ਆతͳෛՙ ๏తϦεΫ
/4'8ը૾ͷݕग़
ֶश༻σʔληοτʢ/4'8ʣ ਖ਼ྫɿ ෛྫɿ ← NSFWը૾
܇࿅ɾֶश
ڭࢣ༗Γֶश ◦ × Ϟσϧ 1.00 0.00
Ϟσϧͷߏ conv 3x3x64 stride 1 conv 3x3x64 stride 1
ReLU ReLU conv 3x3x128 stride 1 conv 3x3x128 stride 1 ReLU conv 3x3x256 stride 1 conv 3x3x256 stride 1 ReLU output 1 256x256x1 max_pool 2x2 stride 2 max_pool 2x2 stride 2 ReLU ReLU Sigmoid max_pool 2x2 stride 2 conv 3x3x64 stride 1 ReLU fc 768 ReLU bn bn bn
Sigmoid
# モデル定義 NUM_CLASSES = 1 NAME = 'model3' IMAGE_SIZE =
256 CHANNELS = 3 def prepare_layers(image, training=False): with tf.variable_scope('inference'): conv1 = tf.layers.conv2d(image, 64, [3, 3], [1, 1], padding='SAME', activation=tf.nn.relu, use_bias=False, trainable=training, name='conv1_1') conv1 = tf.layers.conv2d(conv1, 64, [3, 3], [1, 1], padding='VALID', activation=tf.nn.relu, use_bias=False, trainable=training, name='conv1_2') conv1 = tf.layers.batch_normalization(conv1, trainable=training, name='bn_1')
conv2 = tf.layers.conv2d(pool1, 128, [3, 3], [1, 1], padding='VALID', activation=tf.nn.relu,
use_bias=False, trainable=training, name='conv2_1') conv2 = tf.layers.conv2d(conv2, 128, [3, 3], [1, 1], padding='VALID', activation=tf.nn.relu, use_bias=False, trainable=training, name='conv2_2') conv2 = tf.layers.batch_normalization(conv2, trainable=training, name='bn_2') pool2 = tf.layers.max_pooling2d(conv2, [2, 2], [2, 2])
conv3 = tf.layers.conv2d(pool2, 256, [3, 3], [1, 1], padding='VALID', activation=tf.nn.relu,
use_bias=False, trainable=training, name='conv4_1') conv3 = tf.layers.conv2d(conv3, 256, [3, 3], [1, 1], padding='VALID', activation=tf.nn.relu, use_bias=False, trainable=training, name='conv4_2') conv3 = tf.layers.batch_normalization(conv3, trainable=training, name='bn_4') pool3 = tf.layers.max_pooling2d(conv3, [2, 2], [2, 2]) conv = tf.layers.conv2d(pool3, 64, [1, 1], [1, 1], padding='VALID', activation=tf.nn.relu, use_bias=True, trainable=training, name='conv') return conv
def output_layers(prev, batch_size, keep_prob=0.8, training=False): flatten = tf.reshape(prev, [batch_size, -1])
fc1 = tf.layers.dense(flatten, 768, trainable=training, activation=tf.nn.relu, name='fc1') fc1 = tf.layers.dropout(fc1, rate=keep_prob, training=training) output = tf.layers.dense(fc1, NUM_CLASSES, trainable=training, activation=None, name='output') return output
def _loss(logits, labels, batch_size, positive_ratio): cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits( labels=labels, logits=logits)
loss = tf.reduce_mean(cross_entropy) return loss def _init_optimizer(learning_rate): return tf.train.AdamOptimizer(learning_rate=learning_rate) ޡࠩؔͱ࠷దԽΞϧΰϦζϜ
ֶशΛ্ख͘ਐΊΔ
ਖ਼ྫɾෛྫͷൺ ਖ਼ྫɿ ෛྫɿ ← NSFWը૾ NSFW
def _hard_negative_mining(loss, labels, batch_size): positive_count = tf.reduce_sum(labels) positive_count = tf.reduce_max((positive_count,
1)) negative_count = positive_count * HARD_SAMPLE_MINING_RATIO negative_count = tf.reduce_max((negative_count, 1)) negative_count = tf.reduce_min((negative_count, batch_size)) positive_losses = loss * labels negative_losses = loss - positive_losses top_negative_losses, _ = tf.nn.top_k(negative_losses, k=tf.cast(negative_count, tf.int32)) loss = (tf.reduce_sum(positive_losses / positive_count) + tf.reduce_sum(top_negative_losses / negative_count)) return loss )BSE/FHBUJWF.JOJOH
ֶशڥʢ͘͞ΒͷߴՐྗίϯϐϡʔςΟϯάʣ $169FPO$PSFʷ .FNPSZ(# 44%(# (F'PSDF(595*5"/9ʢ1BTDBMΞʔΩςΫνϟʣ(#ʷ (F'PSDF(595Jʢ1BTDBMΞʔΩςΫνϟʣ(#ʷ
ֶश݅ ޡࠩؔަࠩΤϯτϩϐʔ ࠷దԽΞϧΰϦζϜ"EBN ֶश όοναΠζ
طଘͷσʔληοτʹਪʢJOGFSFODFʣΛ࣮ߦ Downloader σʔληοτ Tagઃఆ inference trainer ֶशࡁΈϞσϧ ֶश༻σʔληοτ
ਪ݁Ռ /4'8 Ұൠը૾ NSFW 8.6%
ֶश༻σʔληοτʢ/4'8ʣ ਖ਼ྫɿ ɹˠɹ ෛྫɿ ɹˠɹ
܇࿅ɾֶशʹ͔͔Δܭࢉ࣌ؒ
σϞ (16ɾ$16ͷൺֱ
$16ɾ(16ͷൺֱʢCBUDI4J[Fʣ 5*5"/9 TFDTUFQ 9FPO$PSF TFDTUFQ ࠓճͷϞσϧͷֶशʹ͍ͭͯ 5*5"/9ͷํ͕ഒ͍ʂ
$16ɾ(16ͷൺֱʢCBUDI4J[F ʣ 5*5"/9 (595J TFDTUFQ 9FPO$PSF TFDTUFQ
ࠓճͷϞσϧͷֶशʹ͍ͭͯ (16ʷͷํ͕ഒ͍ʂ
ࠓޙͷ՝
σʔληοταʔόʔͷ৴པੑ্
JOGFSFODFʢਪʣͷͨΊͷܭࢉࢿݯͷ֬อ Downloader σʔληοτ Tagઃఆ inference trainer ֶशࡁΈϞσϧ ֶश༻σʔληοτ
TAGS = [ 'original_art', 'nsfw', 'like', 'photo', 'illust', 'comic', 'face',
'girl', 'megane', ϥϕϧʢλάʣ 'school_uniform', 'blazer_uniform', 'sailor_uniform', 'gl', 'kemono', 'boy', 'bl', 'cat', 'dog', 'food', 'dislike', ]
.PWJEJVT
ਪΛ.PWJEJVTҠߦ Downloader σʔληοτ Tagઃఆ trainer ֶशࡁΈϞσϧ ֶश༻σʔληοτ inference
ΫϥεఆϞσϧ conv 3x3x64 stride 1 conv 3x3x64 stride 1
ReLU ReLU conv 3x3x128 stride 1 conv 3x3x128 stride 1 ReLU conv 3x3x256 stride 1 conv 3x3x256 stride 1 ReLU output 20 256x256x1 max_pool 2x2 stride 2 max_pool 2x2 stride 2 ReLU ReLU Sigmoid max_pool 2x2 stride 2 conv 3x3x64 stride 1 ReLU fc 768 ReLU bn bn bn
C-LIS CO., LTD. ຊࢿྉɺ༗ݶձࣾγʔϦεͷஶ࡞Ͱ͢ɻຊࢿྉͷશ෦ɺ·ͨҰ෦ʹ͍ͭͯɺஶ࡞ऀ͔ΒจॻʹΑΔڐΛಘͣʹෳ͢Δ͜ͱې͡ΒΕ͍ͯ·͢ɻ 5IF"OESPJE4UVEJPJDPOJTSFQSPEVDFEPSNPEJpFEGSPNXPSLDSFBUFEBOETIBSFECZ(PPHMFBOEVTFEBDDPSEJOHUPUFSNTEFTDSJCFEJOUIF$SFBUJWF$PNNPOT"UUSJCVUJPO-JDFOTF ໊֤ɾϒϥϯυ໊ɺձ໊ࣾͳͲɺҰൠʹ֤ࣾͷඪ·ͨొඪͰ͢ɻຊࢿྉதͰɺɺɺäΛׂѪ͍ͯ͠·͢ɻ 5IF"OESPJESPCPUJTSFQSPEVDFEPSNPEJpFEGSPNXPSLDSFBUFEBOETIBSFECZ(PPHMFBOEVTFEBDDPSEJOHUPUFSNTEFTDSJCFEJOUIF$SFBUJWF$PNNPOT"UUSJCVUJPO-JDFOTF https://speakerdeck.com/keiji/20171209-sakura-ml-night