TensorFlow的Dataset的padded_batch使用

 

padded_batch API如下

padded_batch(
    batch_size, padded_shapes=None, padding_values=None, drop_remainder=False
)

注意参数drop_remainder用来约束最后一个batch是不是要丢掉,当这个batch样本数少于batch_size时,比如batch_size = 3,最后一个batch只有2个样本。默认是不丢掉

padded_batch是非常见的一个操作,比如对一个变长序列,通过padding操作将每个序列补成一样的长度。

特点:

1)padded_shapes使用默认值或者设置为-1,那么每个batch padding后每个维度就是跟这个者个batch的样本各个维度最大值保持一致

2)当shape固定为特定的size时,那么每个batch的shape就是一样的。如果

 


A = tf.data.Dataset.range(1, 6, output_type=tf.int32).map(lambda x: tf.fill([x], x))
for item in A.as_numpy_iterator():
  print(item)

结果如下:

[1]
[2 2]
[3 3 3]
[4 4 4 4]
[5 5 5 5 5]

padded_batch操作:

  • padded_shapes不设置或者设置为-1

padded_shapes设置为-1跟不设置该参数的效果一样,就是按每个batch里的最大的size去进行padding

B = A.padded_batch(2, padded_shapes = [-1])
for item in B.as_numpy_iterator():
  print("*" * 20)
  print(item)

打印结果如下:

可以看出事每个batch的里的shape保持一致,长度不够的补0

********************
[[1 0]
 [2 2]]
********************
[[3 3 3 0]
 [4 4 4 4]]
********************
[[5 5 5 5 5]]
  • padded_shapes设置为固定值 

B = A.padded_batch(2, padded_shapes = [6])
for item in B.as_numpy_iterator():
  print("*" * 20)
  print(item)
  

打印结果:

可见每个batch的每个序列长度都是6,不足就补0

********************
[[1 0 0 0 0 0]
 [2 2 0 0 0 0]]
********************
[[3 3 3 0 0 0]
 [4 4 4 4 0 0]]
********************
[[5 5 5 5 5 0]]

 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,根据你的描述,我尝试编写了一个`epoch_train_with_batch`函数,如下所示: ```python import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, TensorDataset from torch.nn.utils.rnn import pack_padded_sequence import numpy as np # 定义VAE编码器 class MLP(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(MLP, self).__init__() self.fc1 = nn.Linear(input_size, hidden_size) self.fc2 = nn.Linear(hidden_size, hidden_size) self.fc3 = nn.Linear(hidden_size, output_size) def forward(self, x): x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x)) x = self.fc3(x) return x class GAT(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(GAT, self).__init__() self.fc1 = nn.Linear(input_size, hidden_size) self.fc2 = nn.Linear(hidden_size, output_size) def forward(self, x): x = torch.relu(self.fc1(x)) x = self.fc2(x) return x class VAE(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(VAE, self).__init__() self.encoder1 = MLP(input_size[2]*input_size[3], hidden_size, output_size) self.encoder2 = GAT(input_size[2]*input_size[3], hidden_size, output_size) self.fc1 = nn.Linear(2*output_size, output_size) self.fc21 = nn.Linear(output_size, output_size) self.fc22 = nn.Linear(output_size, output_size) self.fc3 = nn.Linear(output_size, 2*output_size) self.decoder = nn.Linear(output_size, input_size[2]*input_size[3]) def encode(self, x1, x2): h1 = self.encoder1(x1.view(-1, x1.shape[2]*x1.shape[3])) h2 = self.encoder2(x2.view(-1, x2.shape[2]*x2.shape[3])) h = torch.cat([h1, h2], dim=1) h = torch.relu(self.fc1(h)) return self.fc21(h), self.fc22(h) def reparameterize(self, mu, logvar): std = torch.exp(0.5*logvar) eps = torch.randn_like(std) return eps.mul(std).add_(mu) def decode(self, z): h = torch.relu(self.fc3(z)) h = self.decoder(h) return h.view(-1, input_size[2], input_size[3]) def forward(self, x1, x2): mu, logvar = self.encode(x1, x2) z = self.reparameterize(mu, logvar) return self.decode(z), mu, logvar # 定义GRU模块 class GRU(nn.Module): def __init__(self, input_size, hidden_size, num_layers): super(GRU, self).__init__() self.gru = nn.GRU(input_size, hidden_size, num_layers, batch_first=True) self.fc1 = nn.Linear(hidden_size, 2) self.conv = nn.Conv2d(1, 1, (2,2)) def forward(self, x): h, _ = self.gru(x) # h shape: (batch_size, seq_len, hidden_size) h = self.fc1(h[:, -1, :]) # 取最后一个时间步的输出 h = h.unsqueeze(1) # h shape: (batch_size, 1, 2) h = self.conv(h) # h shape: (batch_size, 1, 1, 1) return h.view(-1) def epoch_train_with_batch(train_flow_input, train_target, batch_size): # 超参数 hidden_size = 128 latent_dim = 32 num_epochs = 10 learning_rate = 0.001 # 数据处理 train_dataset = TensorDataset(torch.Tensor(train_flow_input), torch.Tensor(train_target)) train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) # 模型定义 model = VAE(train_flow_input.shape, hidden_size, latent_dim) gru_model = GRU(latent_dim, 64, 2) # 损失函数和优化器 criterion_vae = nn.MSELoss() criterion_gru = nn.MSELoss() optimizer = optim.Adam(list(model.parameters()) + list(gru_model.parameters()), lr=learning_rate) # 训练循环 train_loss = [] train_loss_vae = [] for epoch in range(num_epochs): for i, (x, y) in enumerate(train_loader): optimizer.zero_grad() x1 = x[:, :, :, 0] # 取速度特征 x2 = x[:, :, :, 1] # 取星期特征 recon_x, mu, logvar = model(x1, x2) loss_vae = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp()) loss_vae /= batch_size * train_flow_input.shape[1] loss = criterion_vae(recon_x, x1) + loss_vae loss.backward() optimizer.step() train_loss.append(loss.item()) train_loss_vae.append(loss_vae.item()) # 计算GRU模型的损失 z = gru_model(mu.unsqueeze(0)) loss_gru = criterion_gru(z, y) optimizer.zero_grad() loss_gru.backward() optimizer.step() return sum(train_loss)/len(train_loss), sum(train_loss_vae)/len(train_loss_vae) ``` 这段代码定义了一个`VAE`模型和一个`GRU`模型,分别用于特征编码和序列预测。训练循环中,首先对于每个batch,计算VAE模型的损失和梯度,并进行反向传播和优化;然后计算GRU模型的损失和梯度,并进行反向传播和优化。最后返回训练损失和VAE损失的均值。请注意,这段代码可能需要根据具体情况进行修改。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值