用torch 实现 keras.layers.Reshape
时间: 2023-04-05 16:04:36 浏览: 135
可以回答这个问题。在 PyTorch 中,可以使用 torch.reshape() 函数来实现 Keras 中的 Reshape 层。具体实现方法如下:
```python
import torch
import torch.nn as nn
class Reshape(nn.Module):
def __init__(self, shape):
super(Reshape, self).__init__()
self.shape = shape
def forward(self, x):
return torch.reshape(x, self.shape)
```
其中,shape 是一个元组,表示需要将输入张量 reshape 成的形状。例如,如果输入张量的形状为 (batch_size, 10, 20),需要将其 reshape 成形状为 (batch_size, 200) 的张量,则可以使用 Reshape((batch_size, 200))。
相关问题
将冒号后面的代码改写成一个nn.module类:import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense, LSTM data1 = pd.read_csv("终极1.csv", usecols=[17], encoding='gb18030') df = data1.fillna(method='ffill') data = df.values.reshape(-1, 1) scaler = MinMaxScaler(feature_range=(0, 1)) data = scaler.fit_transform(data) train_size = int(len(data) * 0.8) test_size = len(data) - train_size train, test = data[0:train_size, :], data[train_size:len(data), :] def create_dataset(dataset, look_back=1): dataX, dataY = [], [] for i in range(len(dataset)-look_back-1): a = dataset[i:(i+look_back), 0] dataX.append(a) dataY.append(dataset[i + look_back, 0]) return np.array(dataX), np.array(dataY) look_back = 30 trainX, trainY = create_dataset(train, look_back) testX, testY = create_dataset(test, look_back) trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1])) testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1])) model = Sequential() model.add(LSTM(50, input_shape=(1, look_back), return_sequences=True)) model.add(LSTM(50)) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') model.fit(trainX, trainY, epochs=6, batch_size=1, verbose=2) trainPredict = model.predict(trainX) testPredict = model.predict(testX) trainPredict = scaler.inverse_transform(trainPredict) trainY = scaler.inverse_transform([trainY]) testPredict = scaler.inverse_transform(testPredict) testY = scaler.inverse_transform([testY])
以下是将代码改写成一个nn.module类:
```python
import torch.nn as nn
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense, LSTM
class LSTMModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size, num_layers, look_back):
super().__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.look_back = look_back
self.lstm1 = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.lstm2 = nn.LSTM(hidden_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)
c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)
x = x.view(-1, self.look_back, 1)
out, _ = self.lstm1(x, (h0, c0))
out, _ = self.lstm2(out, (h0, c0))
out = self.fc(out[:, -1, :])
return out
data1 = pd.read_csv("终极1.csv", usecols=[17], encoding='gb18030')
df = data1.fillna(method='ffill')
data = df.values.reshape(-1, 1)
scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(data)
train_size = int(len(data) * 0.8)
test_size = len(data) - train_size
train, test = data[0:train_size, :], data[train_size:len(data), :]
def create_dataset(dataset, look_back=1):
dataX, dataY = [], []
for i in range(len(dataset)-look_back-1):
a = dataset[i:(i+look_back), 0]
dataX.append(a)
dataY.append(dataset[i + look_back, 0])
return np.array(dataX), np.array(dataY)
look_back = 30
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
trainX = np.reshape(trainX, (trainX.shape[0], trainX.shape[1], 1))
testX = np.reshape(testX, (testX.shape[0], testX.shape[1], 1))
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = LSTMModel(input_size=1, hidden_size=50, output_size=1, num_layers=2, look_back=look_back).to(device)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
num_epochs = 6
for epoch in range(num_epochs):
for i, (inputs, labels) in enumerate(zip(trainX, trainY)):
inputs = torch.from_numpy(inputs).float().to(device)
labels = torch.from_numpy(labels).float().to(device)
outputs = model(inputs)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (i+1) % 100 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(trainX)}], Loss: {loss.item():.4f}')
model.eval()
trainPredict = scaler.inverse_transform(model(torch.from_numpy(trainX).float().to(device)).detach().cpu().numpy())
testPredict = scaler.inverse_transform(model(torch.from_numpy(testX).float().to(device)).detach().cpu().numpy())
trainY = scaler.inverse_transform([trainY])
testY = scaler.inverse_transform([testY])
```
这个类接受5个参数,分别是:
- input_size: LSTM的输入维度,对于这个例子来说,input_size=1
- hidden_size: LSTM的隐藏层维度
- output_size: LSTM的输出维度,对于这个例子来说,output_size=1
- num_layers: LSTM的层数
- look_back: 每个样本的序列长度,对于这个例子来说,look_back=30
用tensorflow的layers.Layer模块改写class SelfAttention(nn.Module): def init(self,in_c,out_c,fm_sz,pos_bias = False): super(SelfAttention,self).init() self.w_q = nn.Conv2d(in_channels = in_c,out_channels = out_c,kernel_size = 1) self.w_k = nn.Conv2d(in_channels = in_c,out_channels = out_c,kernel_size = 1) self.w_v = nn.Conv2d(in_channels = in_c,out_channels = out_c,kernel_size = 1) self.pos_code = self.__getPosCode(fm_sz,out_c) self.softmax = nn.Softmax(dim = 2) self.pos_bias = pos_bias def __getPosCode(self,fm_sz,out_c): x = [] for i in range(fm_sz): x.append([np.sin,np.cos][i % 2](1 / (10000 ** (i // 2 / fm_sz)))) x = torch.from_numpy(np.array([x])).float() return torch.cat([(x + x.t()).unsqueeze(0) for i in range(out_c)]) def forward(self,x): q,k,v = self.w_q(x),self.w_k(x),self.w_v(x) pos_code = torch.cat([self.pos_code.unsqueeze(0) for i in range(x.shape[0])]).to(x.device) if self.pos_bias: att_map = torch.matmul(q,k.permute(0,1,3,2)) + pos_code else: att_map = torch.matmul(q,k.permute(0,1,3,2)) + torch.matmul(q,pos_code.permute(0,1,3,2)) am_shape = att_map.shape att_map = self.softmax(att_map.view(am_shape[0],am_shape[1],am_shape[2] * am_shape[3])).view(am_shape) return att_map * v
以下是使用tensorflow的layers.Layer模块改写的代码:
```
import tensorflow as tf
class SelfAttention(tf.keras.layers.Layer):
def __init__(self, in_c, out_c, fm_sz, pos_bias=False):
super(SelfAttention, self).__init__()
self.w_q = tf.keras.layers.Conv2D(filters=out_c, kernel_size=1, input_shape=[None, None, in_c])
self.w_k = tf.keras.layers.Conv2D(filters=out_c, kernel_size=1, input_shape=[None, None, in_c])
self.w_v = tf.keras.layers.Conv2D(filters=out_c, kernel_size=1, input_shape=[None, None, in_c])
self.pos_code = self.__getPosCode(fm_sz, out_c)
self.softmax = tf.keras.layers.Softmax(axis=2)
self.pos_bias = pos_bias
def __getPosCode(self, fm_sz, out_c):
x = []
for i in range(fm_sz):
x.append([np.sin, np.cos][i % 2](1 / (10000 ** (i // 2 / fm_sz))))
x = np.array([x], dtype=np.float32)
return tf.concat([(x + tf.transpose(x)).unsqueeze(0) for i in range(out_c)], axis=0)
def call(self, x):
q, k, v = self.w_q(x), self.w_k(x), self.w_v(x)
pos_code = tf.concat([self.pos_code[None, ...] for i in range(tf.shape(x)[0])], axis=0)
if self.pos_bias:
att_map = tf.matmul(q, tf.transpose(k, perm=[0, 1, 3, 2])) + pos_code
else:
att_map = tf.matmul(q, tf.transpose(k, perm=[0, 1, 3, 2])) + tf.matmul(q, tf.transpose(pos_code, perm=[0, 1, 3, 2]))
am_shape = tf.shape(att_map)
att_map = self.softmax(tf.reshape(att_map, [am_shape[0], am_shape[1], am_shape[2] * am_shape[3]]))
att_map = tf.reshape(att_map, am_shape)
return att_map * v
```
需要注意的是,tensorflow中没有nn.Module这个概念,而是使用tf.keras.layers.Layer作为基类。因此,我们需要在类定义中加入`tf.keras.layers.Layer`,并对一些函数名称进行修改。此外,tensorflow默认使用NHWC格式的数据,因此在调用transpose函数时需要加上perm参数进行转置,以保证维度的正确性。