20171209 Sakura ML Night

Ece52fe9ce913851256726020707febd?s=47 Keiji ARIYAMA
December 09, 2017

20171209 Sakura ML Night

2017年12月9日に大阪で開催された「さくらの機械学習ナイト」の発表資料です。

「TensorFlowによるNSFW(職場で不適切な)画像検出」について。

Ece52fe9ce913851256726020707febd?s=128

Keiji ARIYAMA

December 09, 2017
Tweet

Transcript

  1. C-LIS CO., LTD.

  2. C-LIS CO., LTD.  ༗ࢁܓೋʢ,FJKJ"3*:"."ʣ $-*4$0 -5% "OESPJEΞϓϦ։ൃνϣοτσΩϧ Photo by

    Koji MORIGUCHI (MORIGCHOWDER) ػցֶश͸ͪΐͬͱ΍ͬͨ͜ͱ͋Γ·͢ Twitter΍ͬͯ·ͤΜ
  3. ͘͞ΒͷػցֶशφΠτ    5FOTPS'MPXͰ
 /4'8ը૾ݕग़

  4. 5FOTPS'MPXʢ೥݄ൃදʣ  ػց஌ೳ޲͚ܭࢉϑϨʔϜϫʔΫ ࠷৽όʔδϣϯʢ೥݄ʣ

  5.  ษڧձ΍Ζ͏ͥ

  6.  (PPHMF%FWFMPQFS(SPVQ

  7.  IUUQTHEHLPCFEPPSLFFQFSKQFWFOUT

  8.  Πϯλʔωοτ͔Β ޷Έͷը૾ΛࣗಈͰऩू͍ͨ͠

  9. © ࠜઇΕ͍ ؟ ڸ ͬ ່

  10. ؟ڸ່ͬ൑ఆ  1 0

  11. σʔληοτʢ೥݄࣌఺ʣ ؟ڸ່ͬɹຕ ඇ؟ڸ່ͬຕ  ؟ڸ່ͬ ඇ؟ڸ່ͬ ޡݕग़ ؟ڸ່ͬ ඇ؟ڸ່ͬ

  12. { "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 
  13. ߏ੒  Downloader  σʔληοτ Region + Label ઃఆ rsync

  14. ཧ૝ͷߏ੒  Downloader Face Detection Megane Detection ֬ೝɾमਖ਼ ೝࣝ݁Ռ ֶशʢ܇࿅ʣ

    λΠϜϥΠϯ ϝσΟΞ σʔληοτ ֶशʢ܇࿅ʣ TensorFlow  rsync
  15.  ௅ઓͷաఔΛಉਓࢽʹ

  16. ͞·͟·ͳ՝୊ σʔληοτ͕(#Λ௒͑ͨ͋ͨΓ͔ΒϩʔΧϧ΁ͷಉظ͕ࠔ೉ʹɻ ྖҬʢ3FHJPOʣͷઃఆͱϥϕϧͷ෇༩͸૝૾Ҏ্ʹෛՙ͕ߴ͍ɻ 

  17.  ը૾͕ສຕΛಥഁ σʔλ੔ཧ͕ࢸٸͷ՝୊ʹ

  18.  ໨ඪΛ࠶֬ೝ

  19.  Πϯλʔωοτ͔Β ޷Έͷ؟ڸ່ͬը૾ΛࣗಈͰऩू͍ͨ͠

  20. Ҏલͷߏ੒  Downloader  σʔληοτ Region + Label ઃఆ rsync

  21.  ྖҬʴϥϕϧ

  22. ৽͍͠ߏ੒  Downloader  σʔληοτ Tagઃఆ

  23.  λά megane girl

  24. ؟ڸ່ͬ൑ผϞσϧ  Ϟσϧ 1.00 0.00

  25.  %BUBTFU.BOBHFSGPS"OESPJE

  26.  σϞ

  27. https://twitter.com/35s_00/status/930366666973757441

  28.  https://twitter.com/_meganeco

  29.  /4'8ʢ/PU4BGF'PS8PSLʣ

  30. /4'8ը૾ 

  31. ͞·͟·ͳϦεΫ ࡞ۀͷϊΠζ ਫ਼ਆతͳෛՙ ๏తϦεΫ 

  32.  /4'8ը૾ͷݕग़

  33. ֶश༻σʔληοτʢ/4'8ʣ ਖ਼ྫɿ  ෛྫɿ   ← NSFWը૾

  34.  ܇࿅ɾֶश

  35. ڭࢣ༗Γֶश  ◦ × Ϟσϧ 1.00 0.00

  36. Ϟσϧͷߏ଄  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
  37.  Sigmoid

  38. # モデル定義 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') 
  39. 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]) 
  40. 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 
  41. 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 
  42. 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)  ޡࠩؔ਺ͱ࠷దԽΞϧΰϦζϜ
  43.  ֶशΛ্ख͘ਐΊΔ޻෉

  44. ਖ਼ྫɾෛྫͷൺ཰ ਖ਼ྫɿ  ෛྫɿ   ← NSFWը૾ NSFW

  45. 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
  46. ֶश؀ڥʢ͘͞ΒͷߴՐྗίϯϐϡʔςΟϯάʣ $169FPO$PSFʷ .FNPSZ(# 44%(# (F'PSDF(595*5"/9ʢ1BTDBMΞʔΩςΫνϟʣ(#ʷ (F'PSDF(595Jʢ1BTDBMΞʔΩςΫνϟʣ(#ʷ 

  47. ֶश৚݅ ޡࠩؔ਺ަࠩΤϯτϩϐʔ ࠷దԽΞϧΰϦζϜ"EBN ֶश཰ όοναΠζ 

  48. 

  49. 

  50. طଘͷσʔληοτʹਪ࿦ʢJOGFSFODFʣΛ࣮ߦ  Downloader σʔληοτ Tagઃఆ inference trainer ֶशࡁΈϞσϧ ֶश༻σʔληοτ

  51. ਪ࿦݁Ռ /4'8  Ұൠը૾    NSFW
 8.6%

  52. ֶश༻σʔληοτʢ/4'8ʣ ਖ਼ྫɿ ɹˠɹ  ෛྫɿ ɹˠɹ  

  53. ܇࿅ɾֶशʹ͔͔Δܭࢉ࣌ؒ 

  54. 

  55.  σϞ (16ɾ$16ͷൺֱ

  56. $16ɾ(16ͷ଎౓ൺֱʢCBUDI4J[Fʣ 5*5"/9 TFDTUFQ 9FPO$PSF TFDTUFQ  ࠓճͷϞσϧͷֶशʹ͍ͭͯ͸ 5*5"/9ͷํ͕ഒ଎͍ʂ

  57. $16ɾ(16ͷ଎౓ൺֱʢCBUDI4J[F ʣ 5*5"/9  (595J  TFDTUFQ 9FPO$PSF TFDTUFQ 

    ࠓճͷϞσϧͷֶशʹ͍ͭͯ͸ (16ʷͷํ͕ഒ଎͍ʂ
  58.  ࠓޙͷ՝୊

  59. σʔληοταʔόʔͷ৴པੑ޲্ 

  60. JOGFSFODFʢਪ࿦ʣͷͨΊͷܭࢉࢿݯͷ֬อ  Downloader σʔληοτ Tagઃఆ inference trainer ֶशࡁΈϞσϧ ֶश༻σʔληοτ

  61. 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', ]
  62. .PWJEJVT 

  63. ਪ࿦Λ.PWJEJVT΁Ҡߦ  Downloader σʔληοτ Tagઃఆ trainer ֶशࡁΈϞσϧ ֶश༻σʔληοτ inference

  64. Ϋϥε൑ఆϞσϧ  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
  65. 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