首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在一个简单conv2d+liquid状态机网络中使用"steps_per_epoch“而不是"batch_size”来修复“符号张量”

如何在一个简单conv2d+liquid状态机网络中使用"steps_per_epoch“而不是"batch_size”来修复“符号张量”
EN

Stack Overflow用户
提问于 2019-05-22 00:08:55
回答 3查看 2.5K关注 0票数 1

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

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

代码语言:javascript
复制
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参数,因为符号张量应该产生批量输入数据)。”

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

提前谢谢你。

EN

回答 3

Stack Overflow用户

发布于 2019-05-23 15:26:59

这个错误意味着Fit()正在使用的一个数据张量是一个符号张量。one hot函数返回符号张量。尝试如下所示:

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

我个人没有直接在Keras上尝试过这一点--如果在Keras上不起作用,可以尝试使用tf one hot函数而不是Keras one hot函数。

票数 2
EN

Stack Overflow用户

发布于 2019-05-27 07:15:22

它是通过使用下面的代码来解决的。

代码语言:javascript
复制
import keras
from keras.datasets import mnist
from keras.layers import Convolution2D, Dense, Flatten, Activation, Lambda
from keras.layers.wrappers import TimeDistributed
from keras.models import Sequential
import scipy.io

from keras import backend as K
import tensorflow as tf

import numpy as np
import matplotlib.pyplot as plt 

# 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 = shape[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_neurons = 4096; # number of neurons in the reservoir (same with the last dim of the flatten layer);

RC_MATRIX = K.random_normal([n_neurons, n_neurons], mean=0, stddev=1/n_neurons) # Reservior layer node recurrent connection matrix
C_DECAY = K.constant(0.5) # Diffusive memristor time-to-time decay coefficient

# Load training data from the .mat file
mat_contents = scipy.io.loadmat('mnist_sequence_kerasimport.mat')
x_train = mat_contents['xs_train']
x_test = mat_contents['xs_test']
y_train = mat_contents['ys_train']
y_test = mat_contents['ys_test']
# Reshape x_train, x_test into 5D array
x_train = x_train.reshape(x_train.shape[0], x_train.shape[1], x_train.shape[2], x_train.shape[3], 1)
x_test = x_test.reshape(x_test.shape[0], x_test.shape[1], x_test.shape[2], x_test.shape[3], 1)

#%% Model

model=Sequential();

# Convolution Kernels: Input shape (batch_size, 3, 8, 8, 1), Output shape (batch_size, 3, 8, 8, 64)
model.add(TimeDistributed(Convolution2D(64, (3, 3), strides=1, padding='same', use_bias=False, 
                                        kernel_initializer='random_uniform', trainable=False), input_shape = (x_train.shape[1:])))

model.add(TimeDistributed(Flatten()))

# 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(6, 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 = 2, validation_data = (x_test, y_test), batch_size = 50)
票数 0
EN

Stack Overflow用户

发布于 2019-11-29 11:52:28

尝试对张量使用eval()或numpy()函数,以便将它们转换为numpy数组。

查看:How can I convert a tensor into a numpy array in TensorFlow?

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56242375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档