发现tf在压缩模型方面,有些是做不到的。比如修改梯度更新内容。tf的计算图一点创建就无法修改,但是现在的一些论文中,有对梯队修改,来增加训练速度的方法。我看到torch写的代码,我发现tf做不到。我想未来tf也不会修改,因为上面提到的了,图是无法修改的。
未来一定会学习pytorch或者torch,然后模型转为pb格式,因为tf-serving在布置模型方面有太大的优势。
比如说:这个代码的意思是,在求导过程中,bn层加上l1范数。他这个范数和平时的还不一样。
def updateBN():
# 放到了梯度求导中呀
for m in model.modules():
if isinstance(m, nn.BatchNorm2d):
print(m.weight.data.shape)
m.weight.grad.data.add_(args.s*torch.sign(m.weight.data)) # L1
用tf中的实现;
tf.layers.batch_normalization(
inputs,
axis=-1,
momentum=0.99,
epsilon=0.001,
center=True,
scale=True,
beta_initializer=tf.zeros_initializer(),
gamma_initializer=tf.ones_initializer(),
moving_mean_initializer=tf.zeros_initializer(),
moving_variance_initializer=tf.ones_initializer(),
beta_regularizer=None,
gamma_regularizer=None,
beta_constraint=None,
gamma_constraint=None,
training=False,
trainable=True,
name=None,
reuse=None,
renorm=False,
renorm_clipping=None,
renorm_momentum=0.99,
fused=None,
virtual_batch_size=None,
adjustment=None
)
其中,这个gamma_regularizer参数,给一个l1。这么算能保证在就到时候相同,但是在前向推断中会喝torch实现的不同。
这可能就是现在很多弄ai科研的,都喜欢torch/pytorch的原因吧。
我收回上面的话。在tf.layers的接口中,有相关功能。
tf.layers里面包括两种情况,函数api和类api。他们的区别是,类api提供了很多的方法来处理层。
怎么区分他们呢?
tf.layes.BatchNormalization 类的,有大写字母,
tf.layes.batch_normalization 函数的,只有小写字母
在搭建网络时候,他们两个作用和参数都一样,在backend 更新操作时候,类是可控的,有相关的属性。
用法还是有些不同,拿conv2d举例,可以发现不同。
x = tf.layers.Conv2D( 64, kernel_size=[3, 3], strides=[1, 1], padding='same', activation=None,
kernel_regularizer=weight_decay)(x)
x = tf.layers.conv2d(x,64, kernel_size=[3, 3], strides=[1, 1], padding='same', activation=None,
kernel_regularizer=weight_decay')
下面是tf.layes.BatchNormalization的属性
- activity_regularizer
可选的正则化函数用于该层的输出.
- **dtype**
- **graph**
- input
检索图层的输入张量.
仅适用于图层只有一个输入的情况,即它是否连接到一个输入图层.
返回:
输入张量或输入张量列表.
可能引发的异常:
- AttributeError:如果图层连接到多个输入图层.
- RuntimeError:如果在Eager模式下调用.
- AttributeError:如果未找到入站节点.
- input_shape
检索图层的输入形状.
仅适用于图层只有一个输入,即它是否连接到一个传入层,或者所有输入具有相同形状的情况.
返回:
输入形状,作为整数形状元组(或形状元组列表,每个输入张量一个元组).
可能引发的异常:
- AttributeError:如果图层没有定义的input_shape.
- RuntimeError:如果在Eager模式下调用.
- losses
与此Layer相关的损失.
请注意,在急切执行时,获取此属性会计算正规则.使用图形执行时,已经创建了变量正则化运算,并且只是在这里返回.
返回:
张量列表.
- **name**
- **non_trainable_variables**
- **non_trainable_weights**
- output
检索图层的输出张量.
仅适用于图层只有一个输出,即它是否连接到一个输入层.
返回:
输出张量或输出张量列表.
可能引发的异常:
- AttributeError:如果图层连接到多个输入图层.
- RuntimeError:如果在Eager模式下调用.
- output_shape
检索图层的输出形状.
仅适用于图层具有一个输出,或者所有输出具有相同形状的情况.
返回:
输出形状,作为整数形状元组(或形状元组列表,每个输出张量一个元组).
可能引发的异常:
- AttributeError:如果图层没有定义的输出形状.
- RuntimeError:如果在Eager模式下调用.
- **scope_name**
- **trainable_variables**
- **trainable_weights**
- **updates**
- **variables**
返回所有图层变量/权重的列表.
返回:
变量列表.
- **weights**
返回所有图层变量/权重的列表.
返回:
变量列表.
从功能、搭建方便与否来考虑:
稀疏化建模用tf.layers类api,主要是每层都可以定义一个变量的名字,解析模型参数方便,并且class 的api有很多属性可以用;
剪枝模型用tf.nn,他有很方便的初始化参数的方法,但是产生很多变量,他们的名字辨析费劲。;
搭建普通模型用tf.layers函数api,主要是每层都可以定义一个变量的名字,解析模型参数方便;
画结构图用keras,tf2.0以后,会得到大量的使用,但是不建议用。细微的操作还给上面的呢接口,不过,只是单纯的禁止,处理h5文件更加方便。;
slim遗弃了。
-----------------
再次更新关于slim的.
他有一个好处,别的接口做不到的。
可以的动态的传入bool值,来指定模型中的bn和dropout是否处于训练状态。别的接口这么去做会报错。
tensorflow.python.framework.errors_impl.OperatorNotAllowedInGraphError: using a `tf.Tensor` as a Python `bool` is not allowed in Graph execution. Use Eager execution or decorate this function with @tf.function.
有兴趣的可以去看facenet代码。
它的作用是训练一定epochs后进行评估,测试/评估时候,model中的所有值是固定的。