【问题标题】:Shape of weight variable Tensorflow权重变量 Tensorflow 的形状
【发布时间】:2018-04-04 16:05:52
【问题描述】:

我正在尝试学习如何使用 tf.data.TFRecordDataset(),但我对此感到困惑。我有一个 tfrecords 文件,其中包含我的图像(24K)和标签,并且我已将所有图像的大小调整为 100x100x3。

首先,我用tf.data.TFRecordDataset 加载了我的tfrecords 文件并解析数据和其他内容,正如您在我的代码中看到的那样。然后我写了一个简单的模型来学习tfrecord文件的使用,但是我在尝试运行时遇到了错误。我在互联网上搜索过,但找不到任何答案。

这是我的代码:Train.py

import tensorflow as tf
import numpy as np
import os
import  glob
NUM_EPOCHS = 10
batch_size = 128
def _parse_function(example_proto):
  features = {"train/image": tf.FixedLenFeature((), tf.string, default_value=""),
            "train/label": tf.FixedLenFeature((), tf.int64, default_value=0)}
  parsed_features = tf.parse_single_example(example_proto, features)
  image = tf.decode_raw(parsed_features['train/image'], tf.float32)
  label = tf.cast(parsed_features['train/label'], tf.int32)
  image = tf.reshape(image, [100, 100, 3])
  image = tf.reshape(image, [100*100*3])

  return image, label

filename = 'train_data1.tfrecords'
dataset = tf.data.TFRecordDataset(filename)
dataset = dataset.map(_parse_function)
#dataset = dataset.repeat(NUM_EPOCHS)
dataset = dataset.batch(batch_size=batch_size)

iterator = dataset.make_initializable_iterator()
image, label = iterator.get_next()


w = tf.get_variable(name='Weights',shape= [30000,3] , initializer=tf.random_normal_initializer(0, 0.01))
b = tf.get_variable(name='Biases', shape= [1, 3],initializer=tf.zeros_initializer())

logits = tf.matmul(image, w) + b

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=label, name='Entropy'), name='loss')

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

preds = tf.nn.softmax(logits)
correct_preds = tf.equal(tf.argmax(preds, axis=1), tf.argmax(label, axis=1))
accuracy = tf.reduce_sum(tf.cast(correct_preds, tf.float32))



with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(2):
        sess.run(iterator.initializer)
        total_loss = 0
        n_batches = 0
        try:
            while True:
                _, l = sess.run([optimizer, loss])
                total_loss += l
                n_batches +=1
        except tf.errors.OutOfRangeError:
            pass
        print('Average loss epoch {0}: {1}'.format(i, total_loss/n_batches))

这是图像的输出:

<tf.Tensor 'IteratorGetNext:0' shape=(?, 30000) dtype=float32>

标签是:

<tf.Tensor 'IteratorGetNext:1' shape=(?,) dtype=int32>

这一次我得到了这个错误:

logits 和标签的大小必须相同:logits_size=[128,3] 标签大小=[1,128]。

当我使用label = tf.reshape(label,[128,1]) 将标签(我认为,我在这里做错了)重塑为 [128,1] 时,我会收到此错误:

尺寸大小必须能被 3 整除,但对于 128 'gradients/Entropy/Reshape_grad/Reshape' (op: 'Reshape') 带输入 形状:[128,1],[2],输入张量计算为部分 形状:输入[1] = [?,3]。

我正在尝试对我的 3 个类别进行分类:0 表示自行车,1 表示公共汽车,2 表示汽车。

这是我如何将图像和标签读入tfrecords 的代码。 tfrecordWriter.py

的代码
shuffle_data = True
cat_dog_train_path = './Train/*.jpg'
addrs = glob.glob(cat_dog_train_path)
labels = [0 if 'bike' in addr else 1 if 'bus' in addr else 2 for addr in addrs]

if shuffle_data:
    c = list(zip(addrs, labels))
    shuffle(c)
    addrs, labels = zip(*c)


train_addrs = addrs[:]
train_labels = labels[:]
train_shape = []
def load_image(addr):
    img = cv2.imread(addr)
    img = cv2.resize(img, (100, 100), interpolation=cv2.INTER_AREA)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = img.astype(np.float32)
    return img


def _int64_feature(value):
  return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
def _bytes_feature(value):
  return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))


train_filename = 'train_data1.tfrecords'
# open the TFRecords file
writer = tf.python_io.TFRecordWriter(train_filename)
for i in range(len(train_addrs)):
    print ('Train data: {}/{}'.format(i+1, len(train_addrs)))
    sys.stdout.flush()
    img = load_image(train_addrs[i])
    label = train_labels[i]
    feature = {'train/label': _int64_feature(label),
               'train/image': _bytes_feature(tf.compat.as_bytes(img.tostring()))}
    example = tf.train.Example(features=tf.train.Features(feature=feature))
    writer.write(example.SerializeToString())

writer.close()
sys.stdout.flush()

谢谢

【问题讨论】:

    标签: python python-3.x tensorflow deep-learning tensorflow-datasets


    【解决方案1】:

    问题出在这一行:

        w = tf.get_variable(name='Weights',shape= [None, 100, 100, 3] , initializer=tf.random_normal_initializer(0, 0.01))
    

    您指定您的权重具有 tensorflow 无法处理的形状 shape=[None,100,100,3]。正如错误所说“必须完全定义新变量(权重)的形状”,因此您不能将None 作为权重的维度。在我看来,您将输入张量的形状与权重张量的形状混淆了。看起来您还没有在任何地方展平图像,因此您的模型没有任何意义。你在哪里:

        logits = tf.matmul(image, w) + b
    

    您似乎正试图将此问题视为简单的逻辑回归,并将图像的像素作为单独的特征。这是一种不错的第一种方法(但通常会在图像上使用 Conv-net),但是您必须将图像实际展平为shape=[batchsize,30000] 的形状,然后您的权重将具有shape=[30000,num_labels] 的形状,这样在在矩阵乘法结束时,您将得到形状为shape=[batchsize,num_labels] 的最终输出。根据您的代码编写方式,我觉得您对数学或您要完成的操作背后的操作有一些基本的误解。也许回顾一下你到底想要做什么。

    编辑:这里的问题是对算法在做什么的根本误解。该算法产生 3 个输出,因此标签必须有 3 个对应的标签才能匹配 3 个输出。您的标签不能只有一个数字 - 0,1 或 2,具体取决于类别。您的标签必须是 3 个数字,每个数字都告诉您该图像是否属于该类别。换句话说,您必须使用 3 分量(单热)向量而不是 1 分量编号来标记图像。每张图片的标签应如下所示:

    [1,0,0] - bike
    [0,1,0] - bus
    [0,0,1] - car
    

    因此您的标签形状(128,3) 应该与输出形状(128,3)相同

    【讨论】:

    • 感谢指导。我知道,Conv-net 通常用于图像。但我的目标是学习如何使用 Tfrecords 文件。我重塑了我的图像并使它们变平(tf.reshape(图像,[100 * 100 * 3])),现在我的图像的形状是(?,30000)。但仍然出现错误。这次是:logits 和标签必须相同大小:logits_size=[128,3] labels_size=[1,128]。我的批量大小是 128,我有 3 个班级。我已将 label_size 更改为 [128, 1] 但仍然无法正常工作
    • 1.你有多少个标签?换句话说,您尝试将图像分类到多少类? 2. 请发布(在编辑中)您更新的代码,以便我可以看到您做了什么。
    • 感谢您的帮助,我已经编辑了帖子并添加了我的 tfrecord 文件编写器,您可能会了解我的 tfrecord 它是怎样的
    • 那么,我应该将标签更改为 tfrecordWriter.py 还是 train.py 中的一个热向量?我的意思是我必须在哪里把它们一气呵成?
    • 只要在将它们输入神经网络本身的点之前,您就可以在任何地方将它们设为 one-hot 向量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-12
    • 2017-02-26
    • 2018-06-25
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多