所以基本上我想在 TensorFlow 中实作与此代码相同的目标
def get_function(network, loader):
''' Collect function (features) from the self.network.module.forward_features() routine '''
features = []
for batch_idx, (inputs, targets) in enumerate(loader):
inputs, targets = inputs.to('cpu'), targets.to('cpu')
features.append([f.cpu().data.numpy().astype(np.float16) for f in network.forward_features(inputs)])
return [np.concatenate(list(zip(*features))[i]) for i in range(len(features[0]))]
TensorFlow迭代器有什么干凈的方法吗?
uj5u.com热心网友回复:
要回答你的问题,我只需要确保你理解你的原文 火炬 正确编码。所以,这是你的作业流程
class LeNet(nn.Module):
def forward:
# few bunch of layers
return output
def forward_features:
# same as forward function
return [each layer output]
现在,接下来,您使用该torch_get_function
方法并检索forward_features
模型中定义的函式的所有层输出。该torch_get_function
给出一个总的4个输出作为一个串列,你只挑第一特征的,concate整个批次进行到底。
def torch_get_function(network, loader):
features = []
for batch_idx, (inputs, targets) in enumerate(loader):
print('0', network.forward_features(inputs)[0].shape)
print('1', network.forward_features(inputs)[1].shape)
print('2', network.forward_features(inputs)[2].shape)
print('3', network.forward_features(inputs)[3].shape)
print()
features.append([f... for f in network.forward_features(inputs)])
return [np.concatenate(list(zip(*features))[i]) for i in range(len(features[0]))]
for epoch in epochs:
dataset = torchvision.datasets.MNIST...
dataset = torch.utils.data.Subset(dataset, list(range(0, 1000)))
functloader = torch.utils.data.DataLoader(...)
# for x , y in functloader:
# print('a ', x.shape, y.shape)
# a torch.Size([100, 1, 28, 28]) torch.Size([100])
activs = torch_get_function(net, functloader)
print(activs[0].shape)
break
这就是为什么当我运行你的代码时,我得到了
# These are the 4 output that returned by forward_features(inputs)
0 torch.Size([100, 10, 12, 12])
1 torch.Size([100, 320])
2 torch.Size([100, 50])
3 torch.Size([100, 10])
...
# In the return statement of forward_features -
# You take only the first index feature and concate across batches.
(1000, 10, 12, 12)
因此,您的模型的输入大小为(batch_size, 1, 28, 28)
,最终输出为(1000, 10, 12, 12)
.
让我们在 张量流, 一步步。
import numpy as np
from tqdm import tqdm
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import (Conv2D, Dropout, MaxPooling2D,
Dense, Flatten)
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_test = x_test.astype("float32") / 255.0
x_test = np.reshape(x_test, (-1, 28, 28, 1))
dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test))
dataset = dataset.shuffle(buffer_size=1024).batch(100)
# it's like torch.utils.data.Subset
dataset = dataset.take(1000)
dataset
<TakeDataset shapes: ((None, 28, 28, 1), (None,)), types: (tf.float32, tf.uint8)>
现在让我们构建模型。为了让您熟悉,我正在撰写子类 API。
class LeNet(keras.Model):
def __init__(self, num_classes, input_size=28):
super(LeNet, self).__init__()
self.conv1 = Conv2D(10, (5, 5))
self.conv2 = Conv2D(20, (5, 5))
self.conv2_drop = Dropout(rate=0.5)
self.fc1 = Dense(50)
self.fc2 = Dense(num_classes)
def call(self, inputs, training=None):
x1 = tf.nn.relu(MaxPooling2D(2)(self.conv1(inputs)))
x2 = tf.nn.relu(MaxPooling2D(2)(self.conv2_drop(self.conv2(x1))))
x2 = Flatten()(x2)
x3 = tf.nn.relu(self.fc1(x2))
x4 = tf.nn.softmax(self.fc2(x3), axis=1)
# in tf/keras, when we will call model.fit / model.evaluate
# to train the model only x4 will return
if training:
x4
else: # but when model(input)/model.predict(), we can return many :)
return [x1, x2, x3, x4]
lenet = LeNet(10)
lenet.build(input_shape=(None, 28, 28, 1))
获得所需的功能
features = []
for input, target in tqdm(dataset):
# lenet(...) will give 4 output as we model
# but as we're interested on the first index feature...
features.append(lenet(input, training=False)[0])
print(len(features))
features = np.concatenate(features, axis=0)
features.shape
(10000, 12, 12, 10)
在 tensorflow 中,通道轴默认设定为 last,而不是 torch。在火炬中,你收到了(1000, 10, 12, 12)
,在张量流中,它给了你,(10000, 12, 12, 10)
但你当然可以改变它,(如何)。这是作业colab。
0 评论