DeepLearning
画像認識
TensorFlow

TensorflowでCNNを作る際に使いそうな関数を列挙してみた

More than 1 year has passed since last update.

はじめに

Googleが作成したDeepLearningフレームワークのTensorflow
いろいろ記事が上がっていて非常に面白いですが、実際にNNを組む際に使用する関数はどれ?というのを備忘としてまとめてみました

なお筆者はDeeplearningを大学で学んだわけではなく自己学習しただけなので、間違いも多々あるかと思いますが、後学のため指摘いただけると幸いです

畳込み層で使用

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)

畳込みを行う関数
他にはdepthwise_conv2d, separable_conv2dが存在する

第1引数: input

インプットデータを、4次元([batch, in_height, in_width, in_channels])のテンソルを渡す
一番最初は画像を読み込んだ後、reshape関数で[-1, in_height, in_width, in_channels]と変換し、渡せばよい

第2引数: filter

畳込みでinputテンソルとの積和に使用するweightにあたる
4次元[filter_height, filter_width, in_channels, channel_multiplier] のテンソルを渡す
最後の引数のchannel_multiplierだけchannel数が拡張される

e.g. 3x3x1のフィルタで畳込み、アウトプットを64チャネルにする

フィルタ作成例
weight = tf.random_normal([3, 3, 1, 64]

第3引数: strides

ストライド(=1画素ずつではなく、数画素ずつフィルタの適用範囲を計算するための値)を指定
ただしstrides[0] = strides[3] = 1. とする必要があるため、指定は[1, stride, stride, 1]と先頭と最後は1固定とする

参考: https://www.tensorflow.org/versions/master/api_docs/python/nn.html#conv2d

第4引数: padding

「'SAME'」か「'VALID'」を利用
ゼロパディングを利用する場合はSAMEを指定

tf.nn.bias_add(value, bias, name=None)

重みを積和したものにバイアスを加算する際に使用
アウトプットチャネル数に合わせるのが良い(?)

アウトプットチャネルが64の場合にバイアスを加算する
bias = tf.Variable(tf.random_normal([64]))
return tf.nn.bias_add(tf.nn.conv2d(input, weight, strides=[1, 2, 2, 1], padding='SAME'),bias)

tf.nn.relu (features, name=None)

畳込み層のアクティベーション関数としてReLuを使用する
もちろんsoftmaxやsigmoidも用意されている

第1引数: features

フィルタやバイアスを足しこんだ結果(Wx + b)のテンソルを利用する

使用例
    return tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(input, weight, strides=[1, 2, 2, 1], padding='SAME'),bias), name='conv1')

プーリング層で使用

tf.nn.max_pool(value, ksize, strides, padding, name=None)

最大プーリング用の関数
他にも平均プーリングも用意されている

第1引数: value

inputデータ
畳込み層からの出力データをそのまま与えれば良い

第2引数: ksize

プーリングサイズをしてい
3x3にしたい場合は[1, 3, 3, 1]とすればよい

※第3引数以降はconv2dと同じのため割愛

その他(ドロップアウト、損失関数、訓練など)

tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None)

ドロップアウトを行う関数

第1引数: x

プーリング層からの出力(を正規化して?)をそのまま与えれば良い

第2引数: keep_prob

ドロップアウトする率
公式ドキュメントには「The probability that each element is kept.」とあるから、残す率を指定すればよい(?)

使用例
# 2割をドロップアウトする
tf.nn.dropout(res,0.8)

tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

交差エントロピー
バックプロパゲーションの損失関数として使用できる

使用例
# res = NNの結果として出力層から返された値
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(res, class))

tf.train.AdamOptimizer

訓練を実施する関数
ここで作ったものをSess.runに引き渡し訓練を実施する

使用例
# res = NNの結果として出力層から返された値
optimizer = tf.train.AdamOptimizer.minimize(cost)

共通/事前処理などで使用

tf.reshape(tensor, shape, name=None)

第1引数: tensor

inputとなるテンソルを指定

第2引数: shape

変えたい形を指定
ただし-1を指定した場合には次元が削減されflattenとなる

与えられた画像をNNで必要なheight, width, channelに変換する
例えば28x28のRGBに変換したい場合は以下のようにする

reshape.py
x = tf.reshape(im, [-1, 28, 28, 3])
実行サンプル
>>> import tensorflow as tf
>>> matrix1 = tf.constant([[3, 3],[1, 1],[2,2]])

>>> # 1次元にreshape
>>> r = tf.reshape(matrix1, [-1])
>>> sess = tf.Session()
>>> sess.run(r)
array([3, 3, 1, 1, 2, 2], dtype=int32)

>>> # 2次元にreshape なお[2]とした場合にはエラーが発生する
>>> r = tf.reshape(matrix1, [2, -1])
>>> sess.run(r)
array([[3, 3, 1],
       [1, 2, 2]], dtype=int32)

tf.matmul(a, b, transpose_a=False, transpose_b=False, a_is_sparse=False, b_is_sparse=False, name=None)

テンソル同士の掛け算を行う関数
数値同士の単純な掛け算は tf.mul(x, y, name=None) を使用する

実行サンプル
>>> a = tf.constant([[1,2],[3,4]])
>>> b = tf.constant([[2],[2]])
>>> c = tf.matmul(a, b)
>>> sess = tf.Session()
>>> #計算の結果、[1*2 + 2*2],[3*2 + 4*2]となる
>>> sess.run(c)
array([[ 6],
       [14]], dtype=int32)

tf.reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None)

損失関数などで使用する平均を算出する関数
reduction_indicesで集約する次元を指定する

実行サンプル
>>> a = tf.constant([[1.0,2.0],[3.0,4.0],[5.0,6.0]])

>>> mean = tf.reduce_mean(a)
>>> sess.run(mean)
3.5

>>> mean = tf.reduce_mean(a,0)
>>> sess.run(mean)
array([ 3.,  4.], dtype=float32)

>>> mean = tf.reduce_mean(a,1)
>>> sess.run(mean)
array([ 1.5,  3.5,  5.5], dtype=float32)