首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >全卷积网络,训练误差

全卷积网络,训练误差
EN

Stack Overflow用户
提问于 2017-07-01 03:04:24
回答 2查看 534关注 0票数 0

我很抱歉我不擅长英语。

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

这是我的FCN模型代码:(不使用预训练或预训练的模型)

代码语言:javascript
复制
import tensorflow as tf
import numpy as np

加载MNIST数据

代码语言:javascript
复制
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

卷积层

代码语言:javascript
复制
# 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 - Conv-ReLU - Dropout -Conv-ReLU

定义损失、准确性

代码语言:javascript
复制
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))

训练模式

代码语言:javascript
复制
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,我自己的数据)之间唯一不同的代码是:

占位符

我自己的数据是(128x64x1),标签是“not_eyes”

代码语言:javascript
复制
images = tf.placeholder(tf.float32, [None, 128, 64, 1])
labels = tf.placeholder(tf.int32, [None, 2])

第三卷积层

代码语言:javascript
复制
W3 = tf.Variable(tf.truncated_normal([32, 16, 8, 16], stddev = 0.1))

进料(批次)

代码语言:javascript
复制
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)”是返回批处理数据的函数。守则是:

代码语言:javascript
复制
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

似乎没有任何问题..。(请救救我!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-01 18:04:20

你的投入规模适当吗?jpegs在0-255范围内,需要缩放到-1 - 1。您可以尝试:

代码语言:javascript
复制
 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
EN

Stack Overflow用户

发布于 2017-07-01 03:33:02

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

这里提出了建立卷积模型的一般建议。以下是根据该条提出的示范建议:

输入-> [CONV -> RELU*N ->池?]*M -> FC -> RELU*K -> FC

在集合之前拥有多个CONV->RELU对层可以提高学习的复杂性。尝试使用N=2而不是1。

其他一些建议:

  1. 在准备数据时,将其缩小到比128x64更小的大小。尝试与MNIST数据相同的大小。 image = tf.reshape(image, [28, 28, 1])
  2. 如果您的眼睛/无眼图像是彩色的,然后将其转换为灰度,并将值规范化为统一范围。您可以使用numpy或tf来完成这个任务,下面是如何使用numpy

灰鳞->

代码语言:javascript
复制
  img = np.dot(np.array(img, dtype='float32'), [[0.2989],[0.5870],[0.1140]])

规范化->

代码语言:javascript
复制
 mean = np.mean(img, dtype='float32')
 std = np.std(img, dtype='float32', ddof=1)
 if std < 1e-4: std = 1.
 img = (img - mean) / std 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44856988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档