本文介绍了如何修复“符号张量"?使用"steps_per_epoch"但不是"batch_size"一个简单的conv2d +液体状态机网中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个简单的conv2d +动态库(具有随机/固定连接的自定义循环层,仅输出最后一个时间步节点状态).如代码所示,将存储库编写为lambda层以实现一个简单的方程式.该模型可以由Keras构建.

I am making a simple conv2d + dynamic reservoir (a customized recurrent layer with random / fixed connections that only outputs the last time step node states). The reservoir is written as a lambda layer to implement a simple equation as shown in the code. The model can be constructed by Keras.

我希望训练模型可以对具有给定批次大小的某些图像序列进行分类. (例如batch_size = 2),因此理想情况下,Keras应该分配大小为2x3x8x8x1的批次,因为数据集的大小为10x3x8x8x1.时间分布的Conv2d层应该返回2x3x6x6x3.随后的自定义展平层应展平非时间尺寸并返回2x3x108.具有108个节点的存储层应返回2x108.最后的读出层应返回2x5.

I hope the model to be trained to classify some image sequences with a given batch size. (e.g. batch_size = 2) So ideally Keras should allocate batches of size 2x3x8x8x1 since the dataset is of the size 10x3x8x8x1. The time distributed Conv2d layer is supposed to return 2x3x6x6x3. The subsequent customized flatten layer should flat non-time dimensions and return 2x3x108. The reservior layer with 108 nodes should return 2x108. And the last read-out layer should return 2x5.

import keras
from keras.layers import Dense, Convolution2D, Activation, Lambda
from keras.layers.wrappers import TimeDistributed
from keras.models import Sequential

from keras import backend as K
import tensorflow as tf

import numpy as np

# Flatten the non-time dimensions
def flatten_tstep(x_in): # Input shape (None, 3, 6, 6, 3), Output shape (None, 3, 108)
    shape = K.shape( x_in ) # tensor shape
    x_out = K.reshape( x_in, [shape[0], shape[1], K.prod(shape[1:])] )
    return x_out

def flatten_tstep_shape( x_shape ) :
    n_batch, n_tsteps, n_rows, n_cols, n_filters = x_shape
    output_shape = ( n_batch, n_tsteps, n_rows * n_cols * n_filters ) # Flatten 
    return output_shape

# Simple Reservior
# Use a single batch as an example, the input (size 3x108) is of 3 time steps to the 108 nodes in the reserivor.
# The states of the nodes are stat_neuron (size 1x108)
# For t in range(3)
#   stat_neuron = stat_neuron * decay_coefficient + input[t, :] + recurrent_connection_matrix * stat_neuron
# End
# This layer effectively returns the states of the node in the last time step
def ag_reservior(x_in): # Input shape (None, 3, 108), Output shape (None, 108)
    shape = K.shape( x_in ) # tensor shape
    stat_neuron = K.zeros([shape[0], shape[2]]) # initialize Neuron states    
    t_step = tf.constant(0) # Initialize time counter, shifted by 1
    t_max = tf.subtract(shape[1], tf.constant(1)) # Maximum time steps, shifted by 1
    x = x_in
    def cond(t_step, t_max, stat_neuron, x):
        return tf.less(t_step, t_max)
    def body(t_step, t_max, stat_neuron, x):
        global RC_MATRIX, C_DECAY # Connection matrix, decay constant
        temp = tf.scalar_mul(C_DECAY, stat_neuron) #  stat_neuron * decay_coefficient    
        temp = tf.add(temp, x[:, t_step, :]) # stat_neuron * decay_coefficient + input[t, :]
        temp = tf.add(temp, tf.einsum('ij,bj->bi', RC_MATRIX, stat_neuron)) # out[batch,i]=sum_j RC_MATRIX[i,j]*stat_neuron[batch,j]
        return [tf.add(t_step, 1), t_max, temp, x]
    res = tf.while_loop(cond, body, [t_step, t_max, stat_neuron, x])
    return res[2]

def ag_reservior_shape( x_shape ) :
    in_batch, in_tsteps, in_nodes = x_shape
    output_shape = ( in_batch, in_nodes )
    return output_shape

#%% Parameters

n_sample = 10; # number of samples;
n_tstep = 3; # number of time steps per sample
n_row = 8; # number of rows per frame
n_col = 8; # number of columns per frame
n_channel = 1; # number of channel

RC_MATRIX = K.random_normal([108, 108]) # Reservior layer node recurrent connection matrix, note there are 108 nodes
C_DECAY = K.constant(0.9) # Recurrent layer node time-to-time decay coefficient

data = K.random_normal([n_sample, n_tstep, n_row, n_col, 1]) # Some random dataset
# data = np.random.randn(n_sample, n_tstep, n_row, n_col, 1)
label = np.random.randint(5, size=n_sample) # Some random dataset labels
label_onehot = K.one_hot(label, 5)

x_train = data
y_train = label_onehot

x_test = data
y_test = label_onehot

#%% Model

model=Sequential();

# Convolution Kernels: Input shape (batch_size, 3, 8, 8, 1), Output shape (batch_size, 3, 6, 6, 3)
model.add(TimeDistributed(Convolution2D(3, (3, 3), strides=1, padding='valid', use_bias=False, 
                                        kernel_initializer='random_uniform', trainable=False), input_shape = (n_tstep, n_row, n_col, n_channel)))

# Flatten non-time dimensions: Input shape (batch_size, 3, 6, 6, 3), Output shape (batch_size, 3, 108)
model.add(Lambda(flatten_tstep, output_shape = flatten_tstep_shape))

# Reservior: Input shape (batch_size 3, 108), Output shape (batch_size, 108)
model.add(Lambda(ag_reservior, output_shape = ag_reservior_shape))

# Reservior Read-out: Input shape (batch_size, 108), Output shape (batch_size, 5)
model.add(Dense(5, use_bias=False))
model.add(Activation('softmax'))

# Check model
model.summary()

#%% Training
opt = keras.optimizers.rmsprop(lr = 0.01, decay = 1e-6)
model.compile(loss='categorical_crossentropy', optimizer = opt, metrics = ['acc'])
history = model.fit(x_train, y_train, epochs = 50, validation_data = (x_test, y_test), batch_size = 2)

但是,Keras说:如果您的数据采用符号张量的形式,则应指定steps_per_epoch参数(而不是batch_size参数,因为期望符号张量会生成成批的输入数据)."

However, Keras said "If your data is in the form of symbolic tensors, you should specify the steps_per_epoch argument (instead of the batch_size argument, because symbolic tensors are expected to produce batches of input data)."

您能建议如何让Keras正确识别批次大小并进行培训吗? (请注意,Conv2d层是固定的,lambda层也是固定的,只有最后一个密集层需要训练.)

Could you advise on how to let Keras correctly recognize the batch size and proceed to the training? (Note that the Conv2d layer is fixed, the lambda layers are also fixed, only the last dense layer needs training.)

谢谢.

推荐答案

该错误表示Fit()使用的数据张量之一是符号张量.一个热标签函数返回一个符号张量.尝试类似的东西:

That error means that one of your data tensors that is being used by Fit() is a symbolic tensor. The one hot label function returns a symbolic tensor. Try something like:

label_onehot = tf.Session().run(K.one_hot(label,5))

label_onehot = tf.Session().run(K.one_hot(label, 5))

我个人还没有直接在Keras上尝试过-如果它不适用于Keras,请尝试使用tf one hot函数而不是Keras one hot函数.

I haven't personally tried this with Keras directly -- if it doesn't work with Keras, try using the tf one hot function instead of the Keras one hot function.

这篇关于如何修复“符号张量"?使用"steps_per_epoch"但不是"batch_size"一个简单的conv2d +液体状态机网中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 17:58