オッサンはDesktopが好き

自作PCや機械学習、自転車のことを脈絡無く書きます

mnistのjpeg画像をtensorflowに入力する、Part 03

いよいよ、実際に学習してみます
主要部のソースです
バッチ用に乱数を生成し、インデックスが合致する画像を読んでいます

# Batch components
validationImages = np.zeros((VALID_DATA_SIZE, IMG_SIZE*IMG_SIZE))
validationLabels = np.zeros((VALID_DATA_SIZE, OUTPUT_SIZE))
testImages = np.zeros((TEST_DATA_SIZE, IMG_SIZE*IMG_SIZE))
testLabels = np.zeros((TEST_DATA_SIZE, OUTPUT_SIZE))

def defineBatchComtents():
    num = np.linspace(0, TRAIN_DATA_SIZE - 1, TRAIN_DATA_SIZE)
    num = num.tolist()
    COMPONENT = []
    total_batch = int(TRAIN_DATA_SIZE/batch_size)
    for i in range(total_batch):
        component = random.sample(num, batch_size)
        COMPONENT.append(component)
        for j in range(batch_size):
            cnt = 0
            while True:
                if(num[cnt] == component[j]):
                    num.pop(cnt)
                    break
                else:
                    cnt += 1
    
    return COMPONENT

def next_batch(batch_component):
    num = sorted(batch_component)
    fileImg = open('./data/trainImage.txt', 'r')
    cnt = 0
    batch_x = []
    batch_y = []
    while True:
        line = fileImg.readline()
        if(not line or cnt == batch_size):
            break
        else:
            val = line.split(' ')
            if(int(num[cnt]) == int(float(val[0]))):
                # image
                image = np.zeros(IMG_SIZE*IMG_SIZE)
                for i in range(IMG_SIZE*IMG_SIZE):
                    image[i] = float(val[i + 1])/255
                batch_x.append(image)
                # label
                label = np.zeros(OUTPUT_SIZE)
                tmp_str = val[IMG_SIZE*IMG_SIZE + 1]
                length = len(tmp_str)
                ans = tmp_str[0:length - 1] # remove \n
                label[int(float(ans))] = 1
                batch_y.append(label)
                cnt += 1
    return np.array(batch_x), np.array(batch_y)

def read_validation_data():
    fileImg = open('./data/validationImage.txt', 'r')
    for i in range(VALID_DATA_SIZE):
        line = fileImg.readline()
        val = line.split(' ')
        validationImages[i, :] = val[1:IMG_SIZE*IMG_SIZE + 1]
        tmp_str = val[IMG_SIZE*IMG_SIZE + 1]
        length = len(tmp_str)
        label = tmp_str[0:length - 1]
        validationLabels[i, int(float(label))] = 1
    
def read_test_data():
    fileImg = open('./data/testImage.txt', 'r')
    for i in range(TEST_DATA_SIZE):
        line = fileImg.readline()
        val = line.split(' ')
        testImages[i, :] = val[1:IMG_SIZE*IMG_SIZE + 1]
        tmp_str = val[IMG_SIZE*IMG_SIZE + 1]
        length = len(tmp_str)
        label = tmp_str[0:length - 1]
        testLabels[i, int(float(label))] = 1

if __name__=='__main__':    
    with tf.device("/gpu:0"):
        with tf.Graph().as_default():
            with tf.variable_scope("scope_model"):
                x = tf.placeholder("float", [None, IMG_SIZE*IMG_SIZE])
                y = tf.placeholder("float", [None, OUTPUT_SIZE])
                keep_prob = tf.placeholder(tf.float32)

                read_validation_data()
                read_test_data()
                
                output, model = inference(x, keep_prob)
                cost = loss(output, y)
                global_step = tf.Variable(0, name='global_step', trainable=False)
                train_op = training(cost, global_step)
                eval_op = evaluate(output, y)
                test_op = write_result(output, y, model)
                summary_op = tf.summary.merge_all()
                saver = tf.train.Saver()
                sess = tf.Session()
                summary_writer = tf.summary.FileWriter("conv_mnist_logs/", graph=sess.graph)
                init_op = tf.global_variables_initializer()
                sess.run(init_op)

                # Training cycle
                for epoch in range(training_epochs):
                    avg_cost = 0.
                    total_batch = int(TRAIN_DATA_SIZE/batch_size)
                    batch_component = defineBatchComtents()
                    # loop over all batchs
                    for i in range(total_batch):
                        minibatch_x, minibatch_y= next_batch(batch_component[i])
                        sess.run(train_op, feed_dict={x: minibatch_x, y: minibatch_y, keep_prob: 0.5})
                        avg_cost += sess.run(cost, feed_dict={x: minibatch_x, y: minibatch_y, keep_prob: 0.5})/total_batch

本に載っていたサンプルでの結果と比較してみるとこんな感じになりました

f:id:changlikesdesktop:20190302114346p:plain

動いていそうですね、、、
ただ、計算はサンプルよりもだいぶ遅かったです(汗)
バッチを変えるたびに画像データをHDから読み込む動きにしたからでしょう
もっと大きなサイズの画像を扱う場合を想定してコードを書きましたが、
mnist程度の画像サイズならば、全てメモリに入れてしまった方が良いですね
その辺の最適化もポイントになりそうです

3回に渡って記録してみました
とても基本的な部分(学習以前の問題)ですが、疎かにできないですね
tensorflowのサンプルでは、
元画像のデータがどのようにネットワークに入っているのか見えないので

応用的な機械学習の構築には、未だ時間が掛かりそうです
着実に前進していこうと思います