TFの移行学習VGG 16ネットワークに基づいて,画像のテストを行う.


vgg16.pyファイル
1.最初はvgg=Vgg 16()で呼び出すと自動的に初期化され、初期化中にディレクトリの下のvgg 16が見つかる.npyファイル、つまりimagenetで訓練した重みファイルをnp.load()ウェイトファイルのロードを完了します.コードは次のとおりです.
class Vgg16:
    def __init__(self, vgg16_npy_path=None):
        if vgg16_npy_path is None:
            path = inspect.getfile(Vgg16)
            path = os.path.abspath(os.path.join(path, os.pardir))
            path = os.path.join(path, "vgg16.npy")
            vgg16_npy_path = path
            print(path)

        self.data_dict = np.load(vgg16_npy_path, encoding='latin1').item()
        #print (self.data_dict)
        print("npy file loaded")

2.次にbuild()メソッドに入り、npyファイルから重みをロードしてVGGネットワーク()を初期化する、すなわちVGGネットワークを構築するプロセスを使用します.最初にロードされたRGB画像は4次元の・[batch,height,width,3]であるため,rgbチャネルの画像をbgr順のチャネルに変更する.チャネルの変換が必要かどうか調べてみましたが、これは自分の定義したモデルによって決まります.必ずしも転化しなければならないわけではない.こちらが転化した後、その検査結果は転化前の結果より少しよく、具体的な原因も分かりません.コードは次のとおりです.
        start_time = time.time()
        print("build model started")
        rgb_scaled = rgb * 255.0

        # Convert RGB to BGR
        red, green, blue = tf.split(axis=3, num_or_size_splits=3, value=rgb_scaled)
        assert red.get_shape().as_list()[1:] == [224, 224, 1]
        assert green.get_shape().as_list()[1:] == [224, 224, 1]
        assert blue.get_shape().as_list()[1:] == [224, 224, 1]
        bgr = tf.concat(axis=3, values=[
            blue - VGG_MEAN[0],
            green - VGG_MEAN[1],
            red - VGG_MEAN[2],
        ])
        assert bgr.get_shape().as_list()[1:] == [224, 224, 3]

3.ネットワークを構築し、入力画像の準備が整い、次にネットワークに画像を送り込む.ネットワークの構成は次のとおりです.
        self.conv1_1 = self.conv_layer(bgr, "conv1_1")
        self.conv1_2 = self.conv_layer(self.conv1_1, "conv1_2")
        self.pool1 = self.max_pool(self.conv1_2, 'pool1')

        self.conv2_1 = self.conv_layer(self.pool1, "conv2_1")
        self.conv2_2 = self.conv_layer(self.conv2_1, "conv2_2")
        self.pool2 = self.max_pool(self.conv2_2, 'pool2')

        self.conv3_1 = self.conv_layer(self.pool2, "conv3_1")
        self.conv3_2 = self.conv_layer(self.conv3_1, "conv3_2")
        self.conv3_3 = self.conv_layer(self.conv3_2, "conv3_3")
        self.pool3 = self.max_pool(self.conv3_3, 'pool3')

        self.conv4_1 = self.conv_layer(self.pool3, "conv4_1")
        self.conv4_2 = self.conv_layer(self.conv4_1, "conv4_2")
        self.conv4_3 = self.conv_layer(self.conv4_2, "conv4_3")
        self.pool4 = self.max_pool(self.conv4_3, 'pool4')

        self.conv5_1 = self.conv_layer(self.pool4, "conv5_1")
        self.conv5_2 = self.conv_layer(self.conv5_1, "conv5_2")
        self.conv5_3 = self.conv_layer(self.conv5_2, "conv5_3")
        self.pool5 = self.max_pool(self.conv5_3, 'pool5')

        self.fc6 = self.fc_layer(self.pool5, "fc6")
        assert self.fc6.get_shape().as_list()[1:] == [4096]
        self.relu6 = tf.nn.relu(self.fc6)

        self.fc7 = self.fc_layer(self.relu6, "fc7")
        self.relu7 = tf.nn.relu(self.fc7)

        self.fc8 = self.fc_layer(self.relu7, "fc8")

        self.prob = tf.nn.softmax(self.fc8, name="prob")

pool 5になると、224*224*3と入力して7*7*512の形式になります.pool 5の出力といえば、学習を移行する過程で、前のボリューム層によって特徴を抽出するため、ここでのボリューム層は一般的にpool 5の前のすべての層を指す.汎用的な画像フィーチャーを抽出するために使用します.その後、3つの全接続レイヤが続き、出力が続きます.
4.これで私たちのネットワークも構築され、入力画像の次元も調整され、VGG 16の重みファイルもロードされました.では、今何枚かの画像をロードしてテストすることができます.(ここで採用したimagenetデータセットで訓練したパラメータを用いて直接ネットワークをロードして判別する)コードは以下の通りである.
import numpy as np
import tensorflow as tf
import vgg16
import utils

img1 = utils.load_image("./test_data/tiger.jpeg")
img2 = utils.load_image("./test_data/hudie.jpeg")

batch1 = img1.reshape((1, 224, 224, 3))
batch2 = img2.reshape((1, 224, 224, 3))

batch = np.concatenate((batch1, batch2), 0)

# with tf.Session(config=tf.ConfigProto(gpu_options=(tf.GPUOptions(per_process_gpu_memory_fraction=0.7)))) as sess:
with tf.device('/cpu:0'):
    with tf.Session() as sess:
        images = tf.placeholder("float", [2, 224, 224, 3])
        feed_dict = {images: batch}

        vgg = vgg16.Vgg16()
        with tf.name_scope("content_vgg"):
            vgg.build(images)

        prob = sess.run(vgg.prob, feed_dict=feed_dict)

ここで私は2枚の画像をロードしてテストしました.入力した画像の次元は4次元なので、画像をロードしてreshape()操作を行い、batchに積み上げてfeed_にあげました.dictでは、ネットワークを呼び出し、sessを通過します.run(y,feed_dict=feed_dict)は、最終的な出力yを得る.このとき,このyはsoftmaxの出力であり,1000個のスコア値であり,各タイプのスコアを表す.