Python TensorFlow-为什么';这不是我学到的东西吗?

Python TensorFlow-为什么';这不是我学到的东西吗?,python,machine-learning,computer-vision,tensorflow,Python,Machine Learning,Computer Vision,Tensorflow,我的目标是用TensorFlow做大事,但我试着从小事做起 我有一些小的灰度方块(带有一些噪音),我想根据它们的颜色对它们进行分类(例如,3类:黑色、灰色、白色)。我编写了一个小Python类来生成正方形和1-hot向量,并修改了它们的基本MNIST示例以将它们输入 但它不会学到任何东西——例如,它总是猜测3个类别≈33%正确 import tensorflow as tf import generate_data.generate_greyscale data_generator = gen

我的目标是用TensorFlow做大事,但我试着从小事做起

我有一些小的灰度方块(带有一些噪音),我想根据它们的颜色对它们进行分类(例如,3类:黑色、灰色、白色)。我编写了一个小Python类来生成正方形和1-hot向量,并修改了它们的基本MNIST示例以将它们输入

但它不会学到任何东西——例如,它总是猜测3个类别≈33%正确

import tensorflow as tf
import generate_data.generate_greyscale

data_generator = generate_data.generate_greyscale.GenerateGreyScale(28, 28, 3, 0.05)
ds = data_generator.generate_data(10000)
ds_validation = data_generator.generate_data(500)
xs = ds[0]
ys = ds[1]
num_categories = data_generator.num_categories

x = tf.placeholder("float", [None, 28*28])
W = tf.Variable(tf.zeros([28*28, num_categories]))
b = tf.Variable(tf.zeros([num_categories]))
y = tf.nn.softmax(tf.matmul(x,W) + b)
y_ = tf.placeholder("float", [None,num_categories])
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

# let batch_size = 100 --> therefore there are 100 batches of training data
xs = xs.reshape(100, 100, 28*28) # reshape into 100 minibatches of size 100
ys = ys.reshape((100, 100, num_categories)) # reshape into 100 minibatches of size 100

for i in range(100):
  batch_xs = xs[i]
  batch_ys = ys[i]
  sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

xs_validation = ds_validation[0]
ys_validation = ds_validation[1]
print sess.run(accuracy, feed_dict={x: xs_validation, y_: ys_validation})
我的数据生成器如下所示:

import numpy as np
import random

class GenerateGreyScale():
    def __init__(self, num_rows, num_cols, num_categories, noise):
        self.num_rows = num_rows
        self.num_cols = num_cols
        self.num_categories = num_categories
        # set a level of noisiness for the data
        self.noise = noise

    def generate_label(self):
        lab = np.zeros(self.num_categories)
        lab[random.randint(0, self.num_categories-1)] = 1
        return lab

    def generate_datum(self, lab):
        i = np.where(lab==1)[0][0]
        frac = float(1)/(self.num_categories-1) * i
        arr = np.random.uniform(max(0, frac-self.noise), min(1, frac+self.noise), self.num_rows*self.num_cols)
        return arr

    def generate_data(self, num):
        data_arr = np.zeros((num, self.num_rows*self.num_cols))
        label_arr = np.zeros((num, self.num_categories))
        for i in range(0, num):
            label = self.generate_label()
            datum = self.generate_datum(label)
            data_arr[i] = datum
            label_arr[i] = label
        #data_arr = data_arr.astype(np.float32)
        #label_arr = label_arr.astype(np.float32)
        return data_arr, label_arr
 ===# EPOCH 0 #===
Error: 0.370000004768
 ===# EPOCH 1 #===
Error: 0.333999991417
 ===# EPOCH 2 #===
Error: 0.282000005245
 ===# EPOCH 3 #===
Error: 0.222000002861
 ===# EPOCH 4 #===
Error: 0.152000010014
 ===# EPOCH 5 #===
Error: 0.111999988556
 ===# EPOCH 6 #===
Error: 0.0680000185966
 ===# EPOCH 7 #===
Error: 0.0239999890327
 ===# EPOCH 8 #===
Error: 0.00999999046326
 ===# EPOCH 9 #===
Error: 0.00400000810623

首先,尝试用随机值而不是零初始化W矩阵——当所有输入的输出都为零时,您不会给优化器任何可处理的东西

而不是:

W = tf.Variable(tf.zeros([28*28, num_categories]))
尝试:


您的问题是,您的梯度无限制地增加/减少,导致损失函数变为nan

看看这个问题:

此外,请确保运行模型的步骤足够多。在train数据集中只运行一次(100次*100个示例),这还不足以使它收敛。至少将其增加到2000左右(在数据集中运行20次)

编辑(无法评论,因此我将在此处添加我的想法): 我链接的帖子的要点是,你可以使用
GradientDescentOptimizer
,只要你将学习率设置为0.001。这就是问题所在,你的学习率对于你使用的损失函数来说太高了


或者,使用不同的损失函数,该函数不会增加/减少太多的梯度。在交叉熵的定义中,使用
tf.reduce_mean
而不是
tf.reduce_sum

虽然dga和syncd的反应很有帮助,但我尝试使用非零权重初始化和更大的数据集,但没有效果。最终起作用的是使用不同的优化算法

我替换了:

train\u step=tf.train.gradientdescentomizer(0.01).最小化(交叉熵)

train\u step=tf.train.AdamOptimizer(0.0005).最小化(交叉熵)

我还将training for loop嵌入到另一个for loop中,以便在几个时期内进行训练,从而实现如下收敛:

import numpy as np
import random

class GenerateGreyScale():
    def __init__(self, num_rows, num_cols, num_categories, noise):
        self.num_rows = num_rows
        self.num_cols = num_cols
        self.num_categories = num_categories
        # set a level of noisiness for the data
        self.noise = noise

    def generate_label(self):
        lab = np.zeros(self.num_categories)
        lab[random.randint(0, self.num_categories-1)] = 1
        return lab

    def generate_datum(self, lab):
        i = np.where(lab==1)[0][0]
        frac = float(1)/(self.num_categories-1) * i
        arr = np.random.uniform(max(0, frac-self.noise), min(1, frac+self.noise), self.num_rows*self.num_cols)
        return arr

    def generate_data(self, num):
        data_arr = np.zeros((num, self.num_rows*self.num_cols))
        label_arr = np.zeros((num, self.num_categories))
        for i in range(0, num):
            label = self.generate_label()
            datum = self.generate_datum(label)
            data_arr[i] = datum
            label_arr[i] = label
        #data_arr = data_arr.astype(np.float32)
        #label_arr = label_arr.astype(np.float32)
        return data_arr, label_arr
 ===# EPOCH 0 #===
Error: 0.370000004768
 ===# EPOCH 1 #===
Error: 0.333999991417
 ===# EPOCH 2 #===
Error: 0.282000005245
 ===# EPOCH 3 #===
Error: 0.222000002861
 ===# EPOCH 4 #===
Error: 0.152000010014
 ===# EPOCH 5 #===
Error: 0.111999988556
 ===# EPOCH 6 #===
Error: 0.0680000185966
 ===# EPOCH 7 #===
Error: 0.0239999890327
 ===# EPOCH 8 #===
Error: 0.00999999046326
 ===# EPOCH 9 #===
Error: 0.00400000810623

编辑-为什么有效:我想问题是我没有手动选择一个好的学习率计划,Adam能够自动生成一个更好的计划。

在我遇到类似问题时发现了这个问题。.我通过缩放功能修复了我的问题

一点背景:我一直在学习tensorflow教程,但是我想使用Kaggle()中的数据进行建模,但一开始我发现了同样的问题:模型根本无法学习。经过几轮的故障排除,我意识到Kaggle数据的规模完全不同。因此,我缩放了数据,使其与tensorflow的MNIST数据集共享相同的比例(0,1)


我只是想在这里加上我的两分钱。以防一些试图遵循教程设置的初学者像我一样陷入困境=)

我现在使用
tf.truncated_normal()
tf.constant()
来计算你和他们的同事建议的权重和偏差。但仍然没有变化:随机猜测y(你确定你的数据没有bug吗?ds[0]100项吗?ds=data_generator.generate_data(10000)xs=ds[0]xs=xs.Reformate(100,100,28*28)如果xs在重塑之前有正确的数字,我会更舒服…嗨。nparray xs以形状(10000,784)开始,然后调整大小为(100,100,784)。我更改了我的帖子,加入了创建数据的类,以便您可以在需要时试用。谢谢!我还一直在玩正方形的大小-非常小的灰度正方形(低于约7x7像素)softmax回归得到0%的误差。然后将宽度或高度增加1个像素,它会跳回到66%的误差。是-对于转移学习,必须检查新数据的预处理方式是否与正在转移的模型的原始训练数据相同。请注意,我遇到的这个问题与学习r有关ate,我用间隔[0,1]内生成的人工数据从头开始训练模型。