- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近开始使用 Pytorch,所以我对它的理解不是很强烈。我以前有一个 1 层 CNN,但想将其扩展到 2 层,但输入和输出 channel 一直在抛出我似乎可以破译的错误。为什么它需要 192 个 channel ?有人可以给我一个指针来帮助我更好地理解这一点吗?我在这里看到了几个相关的问题,但我也不理解这些解决方案。
import numpy as np
import pandas as pd
import torch
import torch.nn as nn
from transformers import BertConfig, BertModel, BertTokenizer
import math
from transformers import AdamW, get_linear_schedule_with_warmup
def pad_sents(sents, pad_token): # Pad list of sentences according to the longest sentence in the batch.
sents_padded = []
max_len = max(len(s) for s in sents)
for s in sents:
padded = [pad_token] * max_len
padded[:len(s)] = s
sents_padded.append(padded)
return sents_padded
def sents_to_tensor(tokenizer, sents, device):
tokens_list = [tokenizer.tokenize(str(sent)) for sent in sents]
sents_lengths = [len(tokens) for tokens in tokens_list]
tokens_list_padded = pad_sents(tokens_list, '[PAD]')
sents_lengths = torch.tensor(sents_lengths, device=device)
masks = []
for tokens in tokens_list_padded:
mask = [0 if token == '[PAD]' else 1 for token in tokens]
masks.append(mask)
masks_tensor = torch.tensor(masks, dtype=torch.long, device=device)
tokens_id_list = [tokenizer.convert_tokens_to_ids(tokens) for tokens in tokens_list_padded]
sents_tensor = torch.tensor(tokens_id_list, dtype=torch.long, device=device)
return sents_tensor, masks_tensor, sents_lengths
class ConvModel(nn.Module):
def __init__(self, device, dropout_rate, n_class, out_channel=16):
super(ConvModel, self).__init__()
self.bert_config = BertConfig.from_pretrained('bert-base-uncased', output_hidden_states=True)
self.dropout_rate = dropout_rate
self.n_class = n_class
self.out_channel = out_channel
self.bert = BertModel.from_pretrained('bert-base-uncased', config=self.bert_config)
self.out_channels = self.bert.config.num_hidden_layers * self.out_channel
self.tokenizer = BertTokenizer.from_pretrained('bert-base-uncased', config=self.bert_config)
self.conv = nn.Conv2d(in_channels=self.bert.config.num_hidden_layers,
out_channels=self.out_channels,
kernel_size=(3, self.bert.config.hidden_size),
groups=self.bert.config.num_hidden_layers)
self.conv1 = nn.Conv2d(in_channels=self.out_channels,
out_channels=48,
kernel_size=(3, self.bert.config.hidden_size),
groups=self.bert.config.num_hidden_layers)
self.hidden_to_softmax = nn.Linear(self.out_channels, self.n_class, bias=True)
self.dropout = nn.Dropout(p=self.dropout_rate)
self.device = device
def forward(self, sents):
sents_tensor, masks_tensor, sents_lengths = sents_to_tensor(self.tokenizer, sents, self.device)
encoded_layers = self.bert(input_ids=sents_tensor, attention_mask=masks_tensor)
hidden_encoded_layer = encoded_layers[2]
hidden_encoded_layer = hidden_encoded_layer[0]
hidden_encoded_layer = torch.unsqueeze(hidden_encoded_layer, dim=1)
hidden_encoded_layer = hidden_encoded_layer.repeat(1, 12, 1, 1)
conv_out = self.conv(hidden_encoded_layer) # (batch_size, channel_out, some_length, 1)
conv_out = self.conv1(conv_out)
conv_out = torch.squeeze(conv_out, dim=3) # (batch_size, channel_out, some_length)
conv_out, _ = torch.max(conv_out, dim=2) # (batch_size, channel_out)
pre_softmax = self.hidden_to_softmax(conv_out)
return pre_softmax
def batch_iter(data, batch_size, shuffle=False, bert=None):
batch_num = math.ceil(data.shape[0] / batch_size)
index_array = list(range(data.shape[0]))
if shuffle:
data = data.sample(frac=1)
for i in range(batch_num):
indices = index_array[i * batch_size: (i + 1) * batch_size]
examples = data.iloc[indices]
sents = list(examples.train_BERT_tweet)
targets = list(examples.train_label.values)
yield sents, targets # list[list[str]] if not bert else list[str], list[int]
def train():
label_name = ['Yes', 'Maybe', 'No']
device = torch.device("cpu")
df_train = pd.read_csv('trainn.csv') # , index_col=0)
train_label = dict(df_train.train_label.value_counts())
label_max = float(max(train_label.values()))
train_label_weight = torch.tensor([label_max / train_label[i] for i in range(len(train_label))], device=device)
model = ConvModel(device=device, dropout_rate=0.2, n_class=len(label_name))
optimizer = AdamW(model.parameters(), lr=1e-3, correct_bias=False)
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=100, num_training_steps=1000) # changed the last 2 arguments to old ones
model = model.to(device)
model.train()
cn_loss = torch.nn.CrossEntropyLoss(weight=train_label_weight, reduction='mean')
train_batch_size = 16
for epoch in range(1):
for sents, targets in batch_iter(df_train, batch_size=train_batch_size, shuffle=True): # for each epoch
optimizer.zero_grad()
pre_softmax = model(sents)
loss = cn_loss(pre_softmax, torch.tensor(targets, dtype=torch.long, device=device))
loss.backward()
optimizer.step()
scheduler.step()
TrainingModel = train()
最佳答案
您在这个问题中的原始代码版本似乎表现不同。你在这里的代码的最终版本给了我一个与你发布的不同的错误,更具体地说 - 这个:
RuntimeError: Calculated padded input size per channel: (20 x 1). Kernel size: (3 x 768). Kernel size can't be greater than actual input size
nn.Conv2d
输入是形状为
(BatchSize, ChannelsIn, Height, Width)
的 4 维张量输出是形状为
(BatchSize, ChannelsOut, HeightOut, WidthOut)
的 4 维张量.最简单的思考方式
nn.Conv2d
适用于像素网格大小为
Height x Width
的二维图像并拥有
ChannelsIn
每个像素有不同的颜色或特征。即使您的输入与实际图像无关,图层的行为仍然相同。最简单的情况是当
nn.Conv2d
不使用填充(如在您的代码中)。在这种情况下,
kernel_size=(kernel_height, kernel_width)
参数指定您可以想象扫过的矩形
Height x Width
输入的矩形并为每个有效位置生成一个像素。无需填充矩形点的坐标可以是任何一对索引
(x, y)
x 介于
0
之间和
Height - kernel_height
和 y 之间
0
和
Width - kernel_width
.因此,输出看起来像一个大小为
(Height - kernel_height + 1) x (Width - kernel_width + 1)
的二维图像。并且将具有为
nn.Conv2d
指定的尽可能多的输出 channel 构造函数,因此输出张量的形状为
(BatchSize, ChannelsOut, Height - kernel_height + 1, Width - kernel_width + 1)
.
groups
不影响层如何改变形状 - 它只控制哪些输入 channel 用作输出 channel 的输入(
groups=1
表示每个输入 channel 用作每个输出 channel 的输入,否则输入和输出 channel 是分成相应数量的组,只有来自组
i
的输入 channel 用作组
i
的输出 channel 的输入)。
(BatchSize, DynamicSize, 768)
与
DynamicSize
取决于输入,例如22. 然后使用
unsqueeze
引入附加维度作为轴 1并重复沿该维度的值转换形状张量
(16, 22, 768)
进入
(16, 12, 22, 768)
.实际上,您将预训练模型的输出用作 12 channel (每个 channel 具有与其他通道相同的值)此处大小为
(22, 768)
的二维图像,其中 22 不固定(取决于批次)。然后应用内核大小为
(3, 768)
的 nn.Conv2d - 这意味着宽度没有“摆动空间”,输出的二维图像的大小为
(20, 1)
并且由于您的层有 192 个 channel ,因此第一个卷积层的输出最终大小具有形状
(16, 192, 20, 1)
.然后你尝试在内核大小
(3, 768)
之上应用第二层卷积。再次,但由于您的二维“图像”现在只是(20 x 1),因此没有适合的有效位置
(3, 768)
矩形内的内核矩形
(20 x 1)
这会导致错误消息
Kernel size can't be greater than actual input size
.
1
)。 1
对于下一层,这对您有用,但更正确的方法是通过切换最后一个维度来转置预训练模型的输出张量 - 获得形状 (16, 768, DynamicSize)
来自 (16, DynamicSize, 768)
然后应用具有 768 个输入 channel 和任意 ChannelsOut
的 nn.Conv1d 层作为输出 channel 和 1d kernel_size=3
(意味着您查看卷积序列的 3 个连续元素)。如果你这样做而不是不填充 (16, 768, DynamicSize)
的输入形状会变成(16, ChannelsOut, DynamicSize-2)
,并在您应用第二个 Conv1d 之后,例如与第一个相同的设置,您将获得形状张量 (16, ChannelsOut, DynamicSize-4)
等(每次一维长度都会缩小 kernel_size-1
)。您也可以随时更改每个后续卷积层的 channel 数/kernel_size。 关于python-3.x - RuntimeError : Given groups=3, 大小为 12 64 3 768 的权重,预期输入 [32, 12, 30, 768] 有 192 个 channel ,但得到了 12 个 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62099558/
我想使用结构 DataResponse 作为 JSON() 的参数来响应用户。通过初始化 DataResponse 的实例,我得到了错误消息,给出了太多的参数,但给出了所有必要的参数。 type Da
我正在尝试将 google-one-tap 与本地主机上的 django 项目集成。所以我在 Client ID for Web 的 Authorized JavaScript origins 中添加
考虑一个类A,我如何编写一个具有与相同行为的模板 A& pretty(A& x) { /* make x pretty */ return x; } A pretty(A&& x) {
我正在使用 Hibernate envers 3.6.3.Final。我可以审核表,我可以看到 _audit 表中填充了 revision_number、revision_type 和实体数据。 我正
问题详细描述如下: 给定两个单词(beginWord 和 endWord)和字典的单词列表,找出是否存在从 beginWord 到 endWord 的转换序列,这样: 一次只能更改一个字母 每个转换后
我正在尝试解析任何选定的 mysql 表的单行的所有列字段和数据。 这背后的原因是为任何给定的单行创建一个类似“通用”的表解析器。 例如,我有这个表“tbl1”: +----+------------
我有一个列表,它可能包含也可能不包含重复的元素。给定另一个列表/元素集,我需要该列表中存在的所有唯一元素的列表。 Input: input_list = ['android', 'ios', 'and
需要编写一个算法来查找给定字符串在给定索引处的 Anagram,并按字典顺序排序。例如: Consider a String: ABC then all anagrams are in sorted
给定学生和铅笔的数量,假设学生有 154 名,铅笔有 93 名,如何用 Python 编写代码来获得比率。 输出:x:y 或者说给定两个数字的百分比并找出比率。 输出:x:y 最佳答案 import
给定学生和铅笔的数量,假设学生有 154 名,铅笔有 93 名,如何用 Python 编写代码来获得比率。 输出:x:y 或者说给定两个数字的百分比并找出比率。 输出:x:y 最佳答案 import
作为一名端到端自动化测试人员,我一直认为 Given、When、Then 语句(在使用 Cucumber 时合并到 Gherkin 语言中)应该只按 1.Given、2.When、3 的顺序出现.然后
我正在尝试以动态方式传递参数。我想使用 Perl 函数 given(){},但由于某种原因,我不能在其他任何东西中使用它。这就是我所拥有的。 print(given ($parity) { wh
我想在 cucumber 中测试以下功能。但是,我只想处理输入文件一次(以下功能中的@Given)。但是,它似乎每次都执行@Given 步骤。是否可以在以下功能中仅执行一次此@Given? @file
我想知道是否可以使用 given 参数来自 pytest 的 parametrize 函数。 示例: import pytest from hypothesis import given from h
在deep learning tutorials ,所有训练数据都存储在一个shared数组中,只有该数组的索引被传递给训练函数以切出一个小批量。我知道这允许将数据保留在 GPU 内存中,而不是将小块
我正在尝试运行以下代码: foreach my $k (keys %rec) { #switch for watchlist figures given ($k) { #line 93
我正在尝试在完全支持的情况下使用 GWT 规范,但是它的示例 official documentation有点简单。 在 SO 中搜索我发现了这个问题: Specs2 - How to define
我使用hypothesis 已经有一段时间了。我想知道如何重用 @given parts。 我有一些大约 20 行,我将整个 @given 部分复制到几个测试用例之上。 一个简单的测试例子 @give
我在运行 rspec 文件时不断收到错误: Failures:
让我们调用一个函数 function doSomethingAndInvokeCallback(callback){ // do something callback(); } 我可以
我是一名优秀的程序员,十分优秀!