TensorFlow - 为什么这个 sofmax 回归没有学到任何东西?
TensorFlow - why doesn't this sofmax regression learn anything?
我的目标是用 TensorFlow 做大事,但我想从小事做起。
我有小的灰度方块(有一点噪音),我想 class根据它们的颜色(例如 3 类:黑色、灰色、白色)对它们进行分类。我写了一些 Python class 来生成正方形和 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
对于初学者,请尝试使用随机值而不是零初始化 W 矩阵 - 当所有输入的输出全为零时,您没有为优化器提供任何可用的东西。
而不是:
W = tf.Variable(tf.zeros([28*28, num_categories]))
尝试:
W = tf.Variable(tf.truncated_normal([28*28, num_categories],
stddev=0.1))
你的问题是你的梯度 increasing/decreasing 没有边界,导致损失函数变成了 nan。
看看这个问题:
此外,请确保您 运行 模型的步数足够。您仅 运行 通过您的训练数据集(100 次 * 100 个示例)对其进行一次处理,这还不足以使其收敛。至少将其增加到 2000 左右(运行通过您的数据集 20 次)。
编辑(无法评论,所以我会在这里添加我的想法):
我链接的 post 的要点是您可以使用 GradientDescentOptimizer
,只要您将学习率设置为 0.001 左右即可。这就是问题所在,您的学习率对于您使用的损失函数来说太高了。
或者,使用不同的损失函数,它不会 increase/decrease 梯度那么大。在 crossEntropy
.
的定义中使用 tf.reduce_mean
而不是 tf.reduce_sum
虽然 dga 和 syncd 的响应很有帮助,但我尝试使用非零权重初始化和更大的数据集,但无济于事。最终起作用的是使用不同的优化算法。
我替换了:
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
和
train_step = tf.train.AdamOptimizer(0.0005).minimize(cross_entropy)
我还将 for 循环的训练嵌入到另一个 for 循环中以训练几个 epoch,从而导致收敛,如下所示:
===# 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(see data here)的数据来做建模,但一开始我一直有同样的问题:模型只是不学习……经过几轮故障排除,我意识到 Kaggle 数据的规模完全不同。因此,我对数据进行了缩放,使其与 tensorflow 的 MNIST 数据集共享相同的 scale(0,1)。
只是觉得我会在这里加上我的两分钱..以防一些尝试按照教程设置的初学者像我一样被卡住=)
我的目标是用 TensorFlow 做大事,但我想从小事做起。
我有小的灰度方块(有一点噪音),我想 class根据它们的颜色(例如 3 类:黑色、灰色、白色)对它们进行分类。我写了一些 Python class 来生成正方形和 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
对于初学者,请尝试使用随机值而不是零初始化 W 矩阵 - 当所有输入的输出全为零时,您没有为优化器提供任何可用的东西。
而不是:
W = tf.Variable(tf.zeros([28*28, num_categories]))
尝试:
W = tf.Variable(tf.truncated_normal([28*28, num_categories],
stddev=0.1))
你的问题是你的梯度 increasing/decreasing 没有边界,导致损失函数变成了 nan。
看看这个问题:
此外,请确保您 运行 模型的步数足够。您仅 运行 通过您的训练数据集(100 次 * 100 个示例)对其进行一次处理,这还不足以使其收敛。至少将其增加到 2000 左右(运行通过您的数据集 20 次)。
编辑(无法评论,所以我会在这里添加我的想法):
我链接的 post 的要点是您可以使用 GradientDescentOptimizer
,只要您将学习率设置为 0.001 左右即可。这就是问题所在,您的学习率对于您使用的损失函数来说太高了。
或者,使用不同的损失函数,它不会 increase/decrease 梯度那么大。在 crossEntropy
.
tf.reduce_mean
而不是 tf.reduce_sum
虽然 dga 和 syncd 的响应很有帮助,但我尝试使用非零权重初始化和更大的数据集,但无济于事。最终起作用的是使用不同的优化算法。
我替换了:
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
和
train_step = tf.train.AdamOptimizer(0.0005).minimize(cross_entropy)
我还将 for 循环的训练嵌入到另一个 for 循环中以训练几个 epoch,从而导致收敛,如下所示:
===# 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(see data here)的数据来做建模,但一开始我一直有同样的问题:模型只是不学习……经过几轮故障排除,我意识到 Kaggle 数据的规模完全不同。因此,我对数据进行了缩放,使其与 tensorflow 的 MNIST 数据集共享相同的 scale(0,1)。
只是觉得我会在这里加上我的两分钱..以防一些尝试按照教程设置的初学者像我一样被卡住=)