Help us understand the problem. What is going on with this article?

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

More than 3 years have 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)

tadOne
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away