質問編集履歴

1 誤字

jo-jo-

jo-jo- score 7

2018/03/20 14:00  投稿

バッチの正規化を使用したモデルに1枚のデータで識別を行いたい
### 前提・実現したいこと
pythonとtensorflowによりResNetを用いて、男女の顔の識別を行う機械学習モデルを作っています。実際に学習済みのモデルに1枚の顔写真を入力すると、上手く判別することができませんでした。原因は活性化関数に入れる前に行われているバッチの正規化(Batch Normalization)であるのではないかと考えています。バッチの正規化を使用したモデルに1枚のデータで識別を行う事ができるようにしたいです。
### 発生している問題・エラーメッセージ
```
バッチの正規化を含んで学習を行ったモデルに対してバッチではなく、
1つのデータをインプットとしていれるにはどのような工夫を行えばいいのでしょうか。
```
### 該当のソースコード
```python
# ============================import============================
import tensorflow as tf
import os
# GPUの無効化
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
import sys
os.chdir("/Users/yuzajotaro/PycharmProjects/GenderRecognitionProjects")
sys.path.append('/Users/yuzajotaro/PycharmProjects/GenderRecognitionProjects')
os.chdir("path")
sys.path.append('path')
import data_set
# ============================init============================
IMAGE_SIZE = 56
LAYER_NUM = 3
LABEL_NUM = 6
CHANNEL = 3
IMAGE_PIXELS = IMAGE_SIZE*IMAGE_SIZE*CHANNEL
LEARNING_RATE = 1e-3
MOMENTUM_RATE = 0.9
LOOP_NUM = 1000
VALIDATION_SIZE = 300
TEST_SIZE = 120
alpha = 1e-3
batch_size = 1
CKPT_PATH = "path"
x = tf.placeholder(tf.float32, [None, IMAGE_PIXELS])
y_ = tf.placeholder(tf.float32, [None, LABEL_NUM])
x_image = tf.reshape(x, [-1, IMAGE_SIZE, IMAGE_SIZE, CHANNEL])
keep_prob = tf.placeholder("float")
# leaky-Relu
def leaky_relu(x, alpha):
   plus = tf.nn.relu(x)
   minus = tf.nn.relu(-x)
   plus = tf.cast(plus, tf.float32)
   minus = tf.cast(minus, tf.float32)
   y = plus - minus*alpha
   return y
# w:init
def weight_variable(shape, name=None):
   initial = tf.truncated_normal(shape, stddev=0.1)
   return tf.Variable(initial, name=name)
def fc_layer(inpt, shape):
   fc_w = weight_variable(shape)
   fc_b = tf.Variable(tf.zeros([shape[1]]))
   fc_h = tf.matmul(inpt, fc_w) + fc_b
   return fc_h
# conv(relu):init
def conv_layer(inpt, filter_shape, stride):
   out_channels = filter_shape[3]
   filter_ = weight_variable(filter_shape)
   conv = tf.nn.conv2d(inpt, filter=filter_, strides=[1, stride, stride, 1], padding="SAME")
   beta = tf.Variable(tf.zeros([out_channels]), name="beta")
   gamma = weight_variable([out_channels], name="gamma")
   mean, var = tf.nn.moments(conv, axes=[0,1,2])
       
   batch_norm = tf.nn.batch_norm_with_global_normalization(conv, mean, var, beta, gamma, 0.001,
                                                           scale_after_normalization=True)
   out = leaky_relu(batch_norm, 1e-3)
   
   return out
def residual_block(inpt, output_depth, down_sample, projection=False):
   input_depth = inpt.get_shape().as_list()[3]
   if down_sample:
       filter_ = [1,2,2,1]
       inpt = tf.nn.max_pool(inpt, ksize=filter_, strides=filter_, padding='SAME')
   conv1 = conv_layer(inpt, [3, 3, input_depth, output_depth], 1)
   conv2 = conv_layer(conv1, [3, 3, output_depth, output_depth], 1)
   if input_depth != output_depth:
       if projection:
           # Option B: Projection shortcut
           input_layer = conv_layer(inpt, [1, 1, input_depth, output_depth], 2)
       else:
           # Option A: Zero-padding
           input_layer = tf.pad(inpt, [[0,0], [0,0], [0,0], [0, output_depth - input_depth]])
   else:
       input_layer = inpt
   res = conv2 + input_layer
   return res
n_dict = {20:1, 32:2, 44:3, 56:4}
# ============resnet====================
n = 32
inpt = x_image
if n < 20 or (n - 20) % 12 != 0:
   print("ResNet depth invalid.")
   sys.exit()
num_conv = (n - 20) // 12 + 1
layers = []
with tf.variable_scope('conv1'):
   conv1 = conv_layer(inpt, [3, 3, 3, 16], 1)
   layers.append(conv1)
for i in range (num_conv):
   with tf.variable_scope('conv2_%d' % (i+1)):
       conv2_x = residual_block(layers[-1], 16, False)
       conv2 = residual_block(conv2_x, 16, False)
       layers.append(conv2_x)
       layers.append(conv2)
for i in range (num_conv):
   down_sample = True if i == 0 else False
   with tf.variable_scope('conv3_%d' % (i+1)):
       conv3_x = residual_block(layers[-1], 32, down_sample)
       conv3 = residual_block(conv3_x, 32, False)
       layers.append(conv3_x)
       layers.append(conv3)
for i in range (num_conv):
   down_sample = True if i == 0 else False
   with tf.variable_scope('conv4_%d' % (i+1)):
       conv4_x = residual_block(layers[-1], 64, down_sample)
       conv4 = residual_block(conv4_x, 64, False)
       layers.append(conv4_x)
       layers.append(conv4)
with tf.variable_scope('fc'):
   global_pool = tf.reduce_mean(layers[-1], [1, 2])
   assert global_pool.get_shape().as_list()[1:] == [64]
   out = fc_layer(global_pool, [64, LABEL_NUM])
   layers.append(out)
   
   y_fc = layers[-1]
   y_conv = tf.nn.softmax(y_fc)
```
### 試したこと
1枚のみの入力の際は全学習データの平均値と分散値をそれぞれmean,varとして使用しようとしたのですが、畳み込み層の1層目~4層目まであるため、それぞれに固定値を設定するのは非合理的だと考え、やめました。
現在は学習とテストを分けずに行っていますが、この課題の糸口がみえたら分けようと思っております。
### 補足情報(FW/ツールのバージョンなど)
このサイトのコードを参考に作成しました。
http://www.iandprogram.net/entry/2016/06/06/180806
  • Python 3.x

    19265 questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • 機械学習

    3212 questions

    機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る