python - 具有可定制隐藏层的 TensorFlow 模型的子类定义
问题描述
我正在学习 TensorFlow 中的模型子类定义
一个非常简单的定义将是这样的
class MyNetwork1(tf.keras.Model):
def __init__(self, num_classes = 10):
super().__init__()
self.num_classes = num_classes
self.input_layer = tf.keras.layers.Flatten()
self.hidden_1 = tf.keras.layers.Dense(128, activation = 'relu')
self.hidden_2 = tf.keras.layers.Dense(64, activation = 'relu')
self.output_layer = tf.keras.layers.Dense(self.num_classes, activation = 'softmax')
def call(self, input_tensor):
x = self.input_layer(input_tensor)
x = self.hidden_1(x)
x = self.hidden_2(x)
x = self.output_layer(x)
return x
建立模型后,
Model1 = MyNetwork1()
Model1.build((None, 28, 28, 1))
它看起来像
Model: "my_network1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten (Flatten) multiple 0
_________________________________________________________________
dense (Dense) multiple 100480
_________________________________________________________________
dense_1 (Dense) multiple 8256
_________________________________________________________________
dense_2 (Dense) multiple 650
=================================================================
Total params: 109,386
Trainable params: 109,386
Non-trainable params: 0
由于此方法无法自定义每层的神经元数量和激活类型,因此我尝试对其进行一些编辑。
我尝试了以下定义
class MyNetwork2(tf.keras.Model):
def __init__(self, num_classes = 2, hidden_dimensions = [100],
hidden_activations = ['relu']):
super().__init__()
self.inputlayer = tf.keras.layers.Flatten()
i = 0
self.hidden_layers = []
for d,a in zip(hidden_dimensions,hidden_activations):
i += 1
setattr(self, 'hidden_' + str(i) ,
tf.keras.layers.Dense(d, activation = a))
self.hidden_layers.append('self.hidden_' + str(i) + '(x)')
self.outputlayer = tf.keras.layers.Dense(num_classes, activation = 'softmax')
self.num_layers = len(hidden_dimensions) + 2
def call(self, inputtensor):
x = self.inputlayer(inputtensor)
for h in self.hidden_layers:
# print(h)
x = eval(h,{}, x)
x = self.outputlayer(x)
return x
在这段代码中,我尝试做与之前的定义相同的事情。
Model2 = MyNetwork2(num_classes = 10, hidden_dimensions = [128,64],
hidden_activations = ['relu', 'relu'])
Model2.build((None, 28, 28, 1))
但是,我遇到了以下错误:
TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got 'self'
如何修复此错误以实现我的目标?
解决方案
似乎是一种非常复杂的做事方式。如果您将字典用于可变数量的层而不是 eval,则一切正常。
class MyNetwork2(tf.keras.Model):
def __init__(self, num_classes=2, hidden_dimensions=[100],
hidden_activations=['relu']):
super(MyNetwork2, self).__init__()
self.inputlayer = tf.keras.layers.Flatten()
self.hidden_layers = dict()
for i, (d, a) in enumerate(zip(hidden_dimensions, hidden_activations)):
self.hidden_layers['hidden_'+str(i)]=tf.keras.layers.Dense(d, activation=a)
self.outputlayer = tf.keras.layers.Dense(num_classes, activation='softmax')
self.num_layers = len(hidden_dimensions) + 2
运行示例:
import tensorflow as tf
import numpy as np
class MyNetwork2(tf.keras.Model):
def __init__(self, num_classes=2, hidden_dimensions=[100],
hidden_activations=['relu']):
super(MyNetwork2, self).__init__()
self.inputlayer = tf.keras.layers.Flatten()
self.hidden_layers = dict()
for i, (d, a) in enumerate(zip(hidden_dimensions, hidden_activations)):
self.hidden_layers['hidden_'+str(i)]=tf.keras.layers.Dense(d, activation=a)
self.outputlayer = tf.keras.layers.Dense(num_classes, activation='softmax')
self.num_layers = len(hidden_dimensions) + 2
def call(self, inputtensor, training=None, **kwargs):
x = self.inputlayer(inputtensor)
for k, v in self.hidden_layers.items():
x = v(x)
x = self.outputlayer(x)
return x
Model2 = MyNetwork2(num_classes = 10, hidden_dimensions = [128,64],
hidden_activations = ['relu', 'relu'])
Model2.build((None, 28, 28, 1))
Model2(np.random.uniform(0, 1, (1, 28, 28, 1)).astype(np.float32))
<tf.Tensor: shape=(1, 10), dtype=float32, numpy=
array([[0.14969216, 0.10196744, 0.0874036 , 0.08350615, 0.18459582,
0.07227989, 0.08263624, 0.08537506, 0.10291573, 0.04962786]],
dtype=float32)>
隐藏层作为字典:
Model2.hidden_layers
{'hidden_0': <tensorflow.python.keras.layers.core.Dense at 0x1891b5c13a0>,
'hidden_1': <tensorflow.python.keras.layers.core.Dense at 0x1891b5c1d00>}
推荐阅读
- unit-testing - 如何在 Corda 4 中使用“MockServices”进行单元测试?
- apache-poi - Apache POI XSSFSimpleShape 矩形和三角形
- node.js - verifyPasswordResetCode 不是函数 firebase Admin SDK
- javascript - 添加动态html行后如何选择文本输入
- flutter - 在颤动中将嵌套列表保存到数据库中
- python - 关于如何在python中删除重复代码的建议
- linux - linux上的docker-compose中的权限被拒绝
- excel - 在 Excel 中插入空白行时使用 OFFSET 函数保持单元格引用
- docker - 无法运行 docker 映像
- javascript - 嵌入文档时不需要的页面边框