我在collate_fn
为 PyTorchDataLoader
类编写自定义函数时遇到问题。我需要自定义函数,因为我的输入有不同的维度。
我目前正在尝试编写斯坦福 MURA 论文的基线实现。该数据集有一组标记的研究。一项研究可能包含多个图像。我创建了一个自定义Dataset
类,使用torch.stack
.
然后将堆叠张量作为输入提供给模型,并对输出列表进行平均以获得单个输出。此实现适用于DataLoader
when batch_size=1
。但是,当我尝试将 设置batch_size
为 8 时,就像原始论文中的情况一样,DataLoader
失败了,因为它用于torch.stack
堆叠批次并且我的批次中的输入具有可变尺寸(因为每个研究可以有多个图像)。
为了解决这个问题,我尝试实现我的自定义collate_fn
函数。
def collate_fn(batch):
imgs = [item['images'] for item in batch]
targets = [item['label'] for item in batch]
targets = torch.LongTensor(targets)
return imgs, targets
Run Code Online (Sandbox Code Playgroud)
然后在我的训练纪元循环中,我像这样循环每个批次:
for image, label in zip(*batch):
label = label.type(torch.FloatTensor)
# wrap them in Variable
image = Variable(image).cuda()
label = Variable(label).cuda()
# forward
output = model(image)
output …
Run Code Online (Sandbox Code Playgroud) 我想要一个带过滤器的2d卷积,这取决于张量流中的小批量样本.任何想法如何做到这一点,特别是如果每个小批量的样品数量未知?
具体而言,我有输入数据inp
的形式的MB x H x W x Channels
,我有过滤器F
的形式的MB x fh x fw x Channels x OutChannels
.
假设是
inp = tf.placeholder('float', [None, H, W, channels_img], name='img_input')
.
我想这样做tf.nn.conv2d(inp, F, strides = [1,1,1,1])
,但这是不允许的,因为F
不能有一个小批量维度.知道如何解决这个问题吗?
问题陈述
我在带有 tensorflow 后端(tf 版本 1.13.1)的 keras 中训练多对多 LSTM,用于标记文本序列,以使用预训练的 GloVe 嵌入来预测序列中每个元素的标记。我的训练方案涉及小批量随机梯度下降,每个小批量矩阵按列填充零以确保输入到网络的长度相等。
至关重要的是,由于任务和数据的性质对我的小批量进行自定义限制,我没有使用 keras 嵌入层。我的目标是为我的零填充单元实现屏蔽机制,以确保损失计算不会将这些单元虚假地视为真正的数据点。
方法
正如 keras文档中所解释的,keras 提供了三种设置掩蔽层的方法:
keras.layers.Embedding
图层配置mask_zero
为True
。keras.layers.Masking
图层;因为我没有使用嵌入层来编码我的训练数据,所以我无法使用带有掩码嵌入层的选项 (1)。因此,我选择了 (2) 并在初始化我的模型后立即添加了一个遮罩层。然而,这种变化似乎没有产生影响。事实上,不仅我的模型的准确性没有提高,在预测阶段模型仍然产生零预测。为什么我的屏蔽层不屏蔽零填充的单元格?这是否与在我的密集层中指定 3 个类而不是 2 个(因此将 0 作为单独的类包括在内)的事实有关?
现有资源的限制
已经提出并回答了类似的问题,但我无法使用它们来解决我的问题。虽然这篇文章没有得到直接回应,但评论中提到的一个链接帖子侧重于如何预处理数据以分配掩码值,这在这里没有争议。然而,掩蔽层初始化与此处使用的相同。这篇文章提到了同样的问题 - 遮罩层对性能没有影响 - 答案以与我相同的方式定义遮罩层,但再次侧重于将特定值转换为遮罩值。最后,这篇文章中的答案提供了相同的层初始化,而无需进一步详细说明。
玩具数据生成
为了重现我的问题,我生成了一个包含两个类 (1,2) 的玩具 10 批次数据集。批是一个可变长度的序列,后填充零,最大长度为 20 个嵌入,每个嵌入向量由 5 个单元组成,因此input_shape=(20,5)
. 这两个类的嵌入值是从不同但部分重叠的截断正态分布生成的,从而为网络创建了一个可学习但并非微不足道的问题。我在下面包含了玩具数据,以便您可以重现该问题。
import pandas as pd
from keras.models import Sequential
from keras.layers import LSTM, …
Run Code Online (Sandbox Code Playgroud) 在 Python 中进行梯度下降的一种方法是自己编写代码。然而,考虑到它在机器学习中的流行程度,我想知道是否有一个可以导入的 Python 库可以为我提供梯度下降方法(最好是小批量梯度下降,因为它通常比批量和随机梯度下降更好) ,但如果我错了,请纠正我)。
我检查了 NumPy 和 SciPy 但找不到任何东西。我没有使用 TensorFlow 的经验,但浏览过他们的在线 API。我找到了 tf.train.GradientDescentOptimizer,但没有参数可以让我选择批量大小,所以我对它的实际含义相当模糊。
抱歉,如果我听起来很天真。我正在自学很多这样的东西。
我的问题是最后。
一个使用小批量 GD 训练并使用最后一个全连接层(第 60 行)中的 dropout的示例CNN
fc1 = tf.layers.dropout(fc1, rate=dropout, training=is_training)
Run Code Online (Sandbox Code Playgroud)
起初我认为tf.layers.dropout
ortf.nn.dropout
随机将列中的神经元设置为零。但我最近发现并非如此。下面的一段代码打印了它的dropout
作用。我将fc0
用作 4 个样本 x 10 的特征矩阵,并将fc
用作退出版本。
import tensorflow as tf
import numpy as np
fc0 = tf.random_normal([4, 10])
fc = tf.nn.dropout(fc0, 0.5)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
a, b = sess.run([fc0, fc])
np.savetxt("oo.txt", np.vstack((a, b)), fmt="%.2f", delimiter=",")
Run Code Online (Sandbox Code Playgroud)
在输出中oo.txt
(原始矩阵:第 1-4 行,删除矩阵:第 5-8 行):
0.10,1.69,0.36,-0.53,0.89,0.71,-0.84,0.24,-0.72,-0.44
0.88,0.32,0.58,-0.18,1.57,0.04,0.58,-0.56,-0.66,0.59
-1.65,-1.68,-0.26,-0.09,-1.35,-0.21,1.78,-1.69,-0.47,1.26
-1.52,0.52,-0.99,0.35,0.90,1.17,-0.92,-0.68,-0.27,0.68
0.20,0.00,0.71,-0.00,0.00,0.00,-0.00,0.47,-0.00,-0.87
0.00,0.00,0.00,-0.00,3.15,0.07,1.16,-0.00,-1.32,0.00
-0.00,-3.36,-0.00,-0.17,-0.00,-0.42,3.57,-3.37,-0.00,2.53
-0.00,1.05,-1.99,0.00,1.80,0.00,-0.00,-0.00,-0.55,1.35
Run Code Online (Sandbox Code Playgroud)
我的理解正确吗?dropout 是在小批量 …
machine-learning neural-network gradient-descent tensorflow mini-batch
我正在尝试对我的神经网络实施小批量训练,而不是更新每个训练样本权重的“在线”随机方法。
\n\n我用 C 开发了一个有点新手的神经网络,我可以调整每层的神经元数量、激活函数等。这是为了帮助我理解神经网络。我已经在 mnist 数据集上训练了网络,但需要大约 200 个 epoch 才能在训练集上实现 20% 的错误率,这对我来说非常糟糕。我目前正在使用在线随机梯度下降来训练网络。我想尝试的是使用小批量。我理解这样的概念:在将误差传播回去之前,我必须累积并平均每个训练样本的误差。当我想计算必须对权重进行的更改时,我的问题就出现了。为了更好地解释这一点,请考虑一个非常简单的感知器模型。一个输入,一个隐藏层,一个输出。为了计算我需要对输入和隐藏单元之间的权重进行的更改,我将使用以下方程:
\n\n\xe2\x88\x82C/\xe2\x88\x82w1= \xe2\x88\x82C/\xe2\x88\x82O*\xe2\x88\x82O/\xe2\x88\x82h*\xe2\x88\x82h/\ xe2\x88\x82w1
\n\n如果你进行偏导数,你会得到:
\n\n\xe2\x88\x82C/\xe2\x88\x82w1=(输出预期答案)(w2)(输入)
\n\n现在这个公式表示您需要将反向传播误差乘以输入。对于在线随机训练来说这是有意义的,因为每次权重更新您使用 1 个输入。对于小批量训练,您使用了许多输入,那么错误会乘以哪个输入?\n我希望您能帮助我。
\n\nvoid propogateBack(void){\n\n\n //calculate 6C/6G\n for (count=0;count<network.outputs;count++){\n network.g_error[count] = derive_cost((training.answer[training_current])-(network.g[count]));\n }\n\n\n\n //calculate 6G/6O\n for (count=0;count<network.outputs;count++){\n network.o_error[count] = derive_activation(network.g[count])*(network.g_error[count]);\n }\n\n\n //calculate 6O/6S3\n for (count=0;count<network.h3_neurons;count++){\n network.s3_error[count] = 0;\n for (count2=0;count2<network.outputs;count2++){\n network.s3_error[count] += (network.w4[count2][count])*(network.o_error[count2]);\n }\n }\n\n\n //calculate 6S3/6H3\n for (count=0;count<network.h3_neurons;count++){\n network.h3_error[count] = (derive_activation(network.s3[count]))*(network.s3_error[count]);\n }\n\n\n //calculate 6H3/6S2\n network.s2_error[count] = = 0;\n for (count=0;count<network.h2_neurons;count++){\n for (count2=0;count2<network.h3_neurons;count2++){ \n network.s2_error[count] …
Run Code Online (Sandbox Code Playgroud) mini-batch ×6
python ×3
tensorflow ×3
c ×1
import ×1
keras ×1
lstm ×1
python-3.x ×1
pytorch ×1