发现tf在压缩模型方面,有些是做不到的--可以实现

发现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中的所有值是固定的。

--------------------------2020年10月04日-----------------------------------

找到了解决办法,

用tf.nn实现。具体实现方法我写在我自己的写的一本压缩模型的书里--《压缩模型·法不责众》。数据还处在小范围流通中,现在已经修正两次了

猜你喜欢

转载自blog.csdn.net/weixin_39875161/article/details/108164600
今日推荐