拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 从TensorFlow中的network.foward()收集特征

从TensorFlow中的network.foward()收集特征

白鹭 - 2022-02-17 2072 0 0

所以基本上我想在 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 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *