完全卷积网络,训练错误

时间:2017-07-01 03:04:25

标签: tensorflow

我很抱歉我不擅长英语。

我正在尝试使用TensorFlow构建自己的完全卷积网络。 但是我用自己的图像数据训练这个模型有困难,而MNIST数据工作正常。

以下是我的FCN型号代码:(未使用预先培训或预建型号

import tensorflow as tf
import numpy as np

加载MNIST数据

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

images_flatten = tf.placeholder(tf.float32, shape=[None, 784])

images = tf.reshape(images_flatten, [-1,28,28,1]) # CNN deals with 3 dimensions
labels = tf.placeholder(tf.float32, shape=[None, 10])
keep_prob = tf.placeholder(tf.float32) # Dropout Ratio

卷积层

# Conv. Layer #1
W1 = tf.Variable(tf.truncated_normal([3, 3, 1, 4], stddev = 0.1))
b1 = tf.Variable(tf.truncated_normal([4], stddev = 0.1))    
FMA = tf.nn.conv2d(images, W1, strides=[1,1,1,1], padding='SAME')
# FMA stands for Fused Multiply Add, which means convolution
RELU = tf.nn.relu(tf.add(FMA, b1))
POOL = tf.nn.max_pool(RELU, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

# Conv. Layer #2
W2 = tf.Variable(tf.truncated_normal([3, 3, 4, 8], stddev = 0.1))
b2 = tf.Variable(tf.truncated_normal([8], stddev = 0.1))    
FMA = tf.nn.conv2d(POOL, W2, strides=[1,1,1,1], padding='SAME')
RELU = tf.nn.relu(tf.add(FMA, b2))
POOL = tf.nn.max_pool(RELU, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME')

# Conv. Layer #3
W3 = tf.Variable(tf.truncated_normal([7, 7, 8, 16], stddev = 0.1))
b3 = tf.Variable(tf.truncated_normal([16], stddev = 0.1))   
FMA = tf.nn.conv2d(POOL, W3, strides=[1,1,1,1], padding='VALID')
RELU = tf.nn.relu(tf.add(FMA, b3))

# Dropout
Dropout = tf.nn.dropout(RELU, keep_prob)

# Conv. Layer #4
W4 = tf.Variable(tf.truncated_normal([1, 1, 16, 10], stddev = 0.1))
b4 = tf.Variable(tf.truncated_normal([10], stddev = 0.1))   
FMA = tf.nn.conv2d(Dropout, W4, strides=[1,1,1,1], padding='SAME')
LAST_RELU = tf.nn.relu(tf.add(FMA, b4))
  

摘要:[Conv-ReLU-Pool] - [Conv-ReLU-Pool] - [Conv-ReLU] - [Dropout] - [Conv-ReLU]

定义损失,准确度

prediction = tf.squeeze(LAST_RELU) 
# Because FCN returns (1 x 1 x class_num) in training

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(prediction, labels))
# First arg is 'logits=' and the other one is 'labels='

optimizer = tf.train.AdamOptimizer(0.001)    
train = optimizer.minimize(loss)

label_max = tf.argmax(labels, 1)
pred_max = tf.argmax(prediction, 1)
correct_pred = tf.equal(pred_max, label_max)
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

培训模式

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

for i in range(10000):
   image_batch, label_batch = mnist.train.next_batch(100)
   sess.run(train, feed_dict={images: image_batch, labels: label_batch, keep_prob: 0.8})
   if i % 10 == 0:
       tr = sess.run([loss, accuracy], feed_dict={images: image_batch, labels: label_batch, keep_prob: 1.0})
       print("Step %d, Loss %g, Accuracy %g" % (i, tr[0], tr[1]))
  

损失:0.784(大约)

     

准确度:94.8%(大约)

问题在于,用MNIST数据训练这个模型效果很好,但是根据我自己的数据,损失总是相同的(0.6319),输出层总是0。

除了第三个卷积层的滤镜大小外,代码没有区别。由先前汇集层压缩的此滤波器大小和输入大小必须具有相同的宽度和宽度。高度。这就是为什么这一层的滤波器大小为[7,7]。

我的模特有什么问题?..

两种情况(MNIST,我自己的数据)之间唯一不同的代码是:

占位符

我自己的数据有(128 x 64 x 1),标签是'眼睛','not_eyes'

images = tf.placeholder(tf.float32, [None, 128, 64, 1])
labels = tf.placeholder(tf.int32, [None, 2])

第3卷积层

W3 = tf.Variable(tf.truncated_normal([32, 16, 8, 16], stddev = 0.1))

喂养(批量)

image_data, label_data = input_data.get_batch(TRAINING_FILE, 10)

sess = tf.Session()
sess.run(tf.global_variables_initializer())
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(sess=sess, coord=coord)

for i in range(10000):
    image_batch, label_batch = sess.run([image_data, label_data])
    sess.run(train, feed_dict={images: image_batch, labels: label_batch, keep_prob: 0.8})
    if i % 10 == 0: ... # Validation part is almost same, too...

coord.request_stop()
coord.join(threads)

这里“input_data”是同一目录中的另一个python文件,“get_batch(TRAINING_FILE,10)”是返回批量数据的函数。代码是:

def get_input_queue(txtfile_name):
    images = []
    labels = [] 

    for line in open(txtfile_name, 'r'): # Here txt file has data's path, label, label number
        cols = re.split(',|\n', line)
        labels.append(int(cols[2]))
        images.append(tf.image.decode_jpeg(tf.read_file(cols[0]), channels = 1)) 

    input_queue = tf.train.slice_input_producer([images, labels], shuffle = True)
    return input_queue

def get_batch(txtfile_name, batch_size):
    input_queue = get_input_queue(txtfile_name)
    image = input_queue[0]
    label = input_queue[1]

    image = tf.reshape(image, [128, 64, 1])

    batch_image, batch_label = tf.train.batch([image, label], batch_size)
    batch_label_one_hot = tf.one_hot(tf.to_int64(batch_label), 2, on_value=1.0, off_value=0.0)
    return batch_image, batch_label_one_hot

似乎没有任何问题...... :(请帮助我...... !!

2 个答案:

答案 0 :(得分:1)

您的输入是否适当缩放? jpegs在[0-255]范围内,需要缩放到[-1 - 1]。你可以尝试:

 image = tf.reshape(image, [128, 64, 1])
 image = tf.scalar_mul((1.0/255), image)
 image = tf.subtract(image, 0.5)
 image = tf.multiply(image, 2.0)

答案 1 :(得分:0)

您的MNIST模型的准确度是多少?如果你发布代码会很有帮助。您是否使用经过训练的模型来评估自己数据的输出。

提供了关于设置卷积模型的一般建议here。 以下是根据文章提出的模型建议: -

  

INPUT - > [[CONV - > RELU] * N - > POOL?] * M - > [FC - > RELU] * K - > FC

在汇集之前拥有多个CONV-> RELU对层可以改善学习复杂功能。尝试使用N = 2而不是1。

其他一些建议:

  1. 在准备数据时,将数据缩小到小于128x64。尝试与MNIST数据相同的大小..

    image = tf.reshape(image, [28, 28, 1])

  2. 如果您的眼睛/无眼图像是彩色的,则将其转换为灰度并将值标准化为单位范围。您可以使用numpy或tf执行此操作,以下是使用numpy

  3. 的方法

    灰阶 - >

      img = np.dot(np.array(img, dtype='float32'), [[0.2989],[0.5870],[0.1140]])
    

    归一化 - >

     mean = np.mean(img, dtype='float32')
     std = np.std(img, dtype='float32', ddof=1)
     if std < 1e-4: std = 1.
     img = (img - mean) / std