質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.90%

CNNのエラー解決とプログラムの理解

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,128

score 13

 エラーの原因とこのCNNのプログラムの詳しい仕組みを知りたいです。

先輩から頂いたプログラムをanaconda promptで動かして、パソコンの画像フォルダに入っている画像の処理をしようとしているのですが、学習がされていなかったり、プログラムをいじる内にエラーが発生したりと、なさけないのですが分からないことだらけです。たたみ込みやプーリングなどの仕組みはざっくりと分かるのですが、プログラムに書かれているコードの一つ一つがどういう役割・意味を持って要るのかが分かりません。

 発生している問題・エラーメッセージ

ValueError: Cannot feed value of shape (32, 28, 28) for Tensor 'input/inputs:0', which has shape '(?, 28, 28, 1)'

 該当のソースコード

# coding: utf-8

# In[10]:

import os
import glob
import sys
import cv2
import tensorflow as tf
import numpy as np
import pandas as pd
from numpy.random import permutation

import time

image_size = 28#次元
image_channnel = 1
imgpx = image_size * image_size * image_channnel#画像サイズ
category = 6
np.random.seed(1)

flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('log_path', '/tmp/cnn/', 'Directory to put the training data')
flags.DEFINE_string('save_name', os.getcwd() + '/var.ckpt', 'path to save variables')
flags.DEFINE_integer('max_steps', 200, 'Number of steps to run trainer')
flags.DEFINE_integer('batch_size', 32, '')
flags.DEFINE_integer('training_epoch', 100, '')
flags.DEFINE_integer('validation_interval', 10, 'validation interval')
flags.DEFINE_float('learning_rate', 1e-4, 'Initial learning rate')
flags.DEFINE_float('dropout_keep_prob', 0.5, '')

def next_batch(data, label, batch_size):
    perm = np.arange(data.shape[0])
    np.random.shuffle(perm)
    return data[perm][:batch_size], label[perm][:batch_size]

def input_placeholder(size, channel, label):
    with tf.name_scope('input') as scope:
        inputs = tf.placeholder("float", [None, size, size, channel], 'inputs')
        labels = tf.placeholder("float", [None, label], 'labels')
    dropout_keep_prob = tf.placeholder("float", None, 'keep_prob')
    learning_rate = tf.placeholder("float", None, name='learning_rate')

    return inputs, labels, dropout_keep_prob, learning_rate

def get_im(path): # reading imagefile and resizing

    img = cv2.imread(path, 0)
    resize = cv2.resize(img, (image_size, image_size))

    return resize

def read_train_data(ho=0): # read train and validation data

    train_data = []
    train_target = []

    for j in range(3, 6): 

        path = 'c:/Users/mitsutaka/Documents/resize/data2/%i/*.png'%(j)#

        files = sorted(glob.glob(path))

        for fl in files:

            flbase = os.path.basename(fl)

            img = get_im(fl)
            img = np.array(img, dtype=np.float32)
            img -= np.mean(img)
            img /= np.std(img)
            tmp = np.zeros(3)
            tmp[int(j-3)] = 1

            train_data.append(img)
            train_target.append(tmp)

    train_data = np.array(train_data, dtype=np.float32)
    train_target = np.array(train_target, dtype=np.uint8)

    # shuffle
    #perm = permutation(len(train_target))#permutation:シャッフル
    #train_data = train_data[perm]
    #train_target = train_target[perm]

    return train_data, train_target

def read_test_data(test_class):

    path = 'c:/Users/mitsutaka/Documents/%i/*.png'%(test_class)#

    files = sorted(glob.glob(path))
    X_test = []
    X_test_id = []

    for fl in files:

        flbase = os.path.basename(fl)

        img = get_im(fl)#画像データの取得
        img = np.array(img, dtype=np.float32)
        img -= np.mean(img)#mean:平均
        img /= np.std(img)#std:標準偏差

        X_test.append(img)
        X_test_id.append(flbase)

    test_data = np.array(X_test, dtype=np.float32)

    return test_data, X_test_id

def inference(images_placeholder, keep_prob):

    def weight(shape):
        initial = tf.truncated_normal(shape, stddev=0.1)       
        return tf.Variable(initial)

    def bias(shape):
        initial = tf.zeros(shape)
        return tf.Variable(initial)

    def conv2d(x, W):#strides幅, padding余白
        return tf.nn.conv2d(x, W, strides=[1,1,1,1], padding='SAME')

    def MaxPooling(x):#tensorflow-APIより使用, 最大値を抽出
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides =[1, 2, 2, 1], padding='SAME')#[1, 2, 2, 1]は2*2の意味 ([1, 3, 3, 1]は3*3の意味)

    x_image = tf.reshape(images_placeholder, [-1, image_size, image_size, image_channnel])
    tf.summary.image('input', x_image, 10)

    #全結合層

    with tf.name_scope('Convolution1') as scope:#畳み込み1層目
        W_conv1 = weight([3, 3, image_channnel, 32])
        b_conv1 = bias([32])#バイアス加算
        h_conv1 = tf.nn.relu(conv2d(images_placeholder, W_conv1) + b_conv1)

    with tf.name_scope('Convolution2') as scope:
        W_conv2 = weight([3, 3, 32, 32])
        b_conv2 = bias([32])
        h_conv2 = tf.nn.relu(conv2d(h_conv1, W_conv2) + b_conv2)



    with tf.name_scope('Pooling1') as scope:
        h_pool1 = MaxPooling(h_conv2)

    with tf.name_scope('FullyConnected1') as scope:
        flat = tf.contrib.layers.flatten(h_pool1)
        tensor_shape = flat.get_shape().as_list()
        W_fc1 = weight([tensor_shape[1], 1024])
        b_fc1 = bias([1024])
        h_fc1 = tf.nn.relu(tf.matmul(flat, W_fc1) + b_fc1)
        h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

    with tf.name_scope('FullyConnected2') as scope:
        W_fc2 = weight([1024, 1024])
        b_fc2 = bias([1024])
        h_fc2 = tf.nn.relu(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
        h_fc2_drop = tf.nn.dropout(h_fc2, keep_prob)

    with tf.name_scope('SoftMax') as scope:
        W_sf = weight([1024, 3])
        b_sf = bias([3])
        y = tf.nn.softmax(tf.matmul(h_fc2_drop, W_sf) + b_sf)

    return y

def loss(logits, labels):

    with tf.name_scope('loss'):
        loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = logits, labels = labels))
        tf.summary.scalar('loss', loss)
    return loss

def training(loss, learning_rate):

    train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss)
    return train_step

def accuracy(logits, labels):

    with tf.name_scope('accuracy'):
        correct_prediction = tf.equal(tf.argmax(logits, 1), tf.argmax(labels, 1))
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
        tf.summary.scalar('accuracy', accuracy)
    return accuracy

def train():

    inputs, labels, dropout_keep_prob, learning_rate =input_placeholder(image_size, image_channnel, 3)
    logits = inference(inputs, dropout_keep_prob)

    acc = accuracy(logits, labels)
    loss_value = loss(logits, labels)
    train = training(loss_value, learning_rate)

    sess = tf.Session()
    sess.run(tf.global_variables_initializer())

    merged = tf.summary.merge_all()
    train_writer = tf.summary.FileWriter(FLAGS.log_path + '/train/', sess.graph)
    validation_writer = tf.summary.FileWriter(FLAGS.log_path + '/validation/')

    saver = tf.train.Saver()
    if os.path.isfile(FLAGS.save_name):
        saver.restore(sess, FLAGS.save_name)

    ho = 0
    train_dataset, train_labels = read_train_data(ho)
    validation_dataset, validation_labels = read_train_data(ho)


    i=0
    print("Initialized")
    cur_learning_rate = FLAGS.learning_rate

    # 処理前の時刻
    t1 = time.time()

    for epoch in range(FLAGS.training_epoch):
        step = 0
        if epoch % 10 == 0 and epoch > 0:
            cur_learning_rate /= 10
        for start, end in zip(range(0, len(train_dataset), FLAGS.batch_size), range(FLAGS.batch_size, len(train_dataset), FLAGS.batch_size)):

            step += 1
            batch_data = train_dataset[start:end]
            batch_labels = train_labels[start:end]
            print(step)
            feed_dict_batch ={inputs: batch_data, labels: batch_labels, dropout_keep_prob: FLAGS.dropout_keep_prob, learning_rate: cur_learning_rate}

            if i% FLAGS.validation_interval == 0:
                summary, _, loss_batch, acc_batch = sess.run([merged, train, loss_value, acc], feed_dict=feed_dict_batch)
                train_writer.add_summary(summary, i)

                summary_valid, loss_valid, acc_valid = sess.run([merged, loss_value, acc], feed_dict={inputs: validation_dataset,
                                                                                                     labels: np.squeeze(validation_labels),
                                                                                                     dropout_keep_prob: 1.0})

                validation_writer.add_summary(summary_valid, i)
                print('----------------------------------')
                print('epoch:', epoch + 1, ', step:', step)
                print("Batch loss: {:.2f}".format(loss_batch))
                print("Batch accuracy: {0:.01%}".format(acc_batch))

                print("Validation loss: {:.2f}".format(loss_valid))
                print("Validation acuuracy: {0:.01%}".format(acc_valid))
            else:
                sess.run(train, feed_dict=feed_dict_batch)
            i+=1

    # 処理後の時刻
    t2 = time.time()

    # 経過時間を表示
    elapsed_time = t2-t1
    print(f"経過時間:{elapsed_time}")

    train_writer.close()
    validation_writer.close()

if __name__ == '__main__':

    param = sys.argv

    run_type = param[1]
    if run_type == 'train':
        train()

 試したこと

ライブラリを変えたりプログラムの書き換えなども行いましたが、コレをいじるとどう変わるのかが理解し切れていません・・・。参考書やサンプルコードを利用してもエラーばかりでどうにも出来ない状況です。

 補足情報(FW/ツールのバージョンなど)

tensorflowは1.10で実施しています

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

入力層に与えるデータは形状が (?, 28, 28, 1) を期待されているのに、(32, 28, 28) となっているというエラーです。

おそらく形状が (28, 28) のグレースケール画像を流そうとしてエラーとなっているので、
np.expand_dims(x, axis=-1) で (32, 28, 28) を (32, 28, 28, 1) にしてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/17 18:12

    すみません。np.expand_dims(x,axis=-1)とはコードのどの部分の事でしょうか?このコードは追加の意味でしょうか?

    キャンセル

  • 2018/10/17 19:52 編集

    コードに追加するという意味です。
    質問のエラー内容を解決する方法として提案しました。

    > プログラムに書かれているコードの一つ一つがどういう役割・意味を持って要るのかが分かりません。

    とのことですが、コード自体は300行近くあるので、具体的にどこがわからないのか示していただけないと全部の行を解説するというのは難しいです。
    質問のコードの理解度はどのような感じでしょうか?
    例えば、「全くわからない」「Deep Learning の理論は理解しているけど、Tensorflow のライブラリの使い方がわからない」「特定の箇所がわからない」など

    キャンセル

  • 2018/10/17 23:07

    「tensorflowのライブラリが使いこなせない」だと思います。 train_dataset, train_labels = read_train_data(ho)
    train_dataset=np.expand_dims(train_dataset,axis=-1)
    validation_dataset, validation_labels = read_train_data(ho)
    validation_dataset=np.expand_dims(validation_dataset,axis=-1)
    で起動しました!ありがとうございます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.90%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る