• ATTENTION NETWORK分析


    1. TensorFlowTrainable类

     1 class TensorFlowTrainable(object):
     2     def __init__(self):
     3         self.parameters = []
     4 
     5     def get_weights(self, dim_in, dim_out, name, trainable=True):
     6         shape = (dim_out, dim_in)
     7         weightsInitializer = tf.constant_initializer(
     8             self.truncated_normal(shape=shape, stddev=0.01, mean=0.))
     9         weights = tf.get_variable(
    10             initializer=weightsInitializer, shape=shape, trainable=True, name=name)
    11         if trainable:
    12             self.parameters.append(weights)  
    13         return weights
    14     def get_4Dweights(self, filter_height, filter_width, in_channels, out_channels, name, trainable=True):
    15         shape = (filter_height, filter_width, in_channels, out_channels)
    16         weightsInitializer = tf.constant_initializer(
    17             self.truncated_normal(shape=shape, stddev=0.01, mean=0))
    18         weights = tf.get_variable(
    19             initializer=weightsInitializer, shape=shape, trainable=True, name=name)
    20         if trainable:
    21             self.parameters.append(weights)
    22         return weights
    23     def get_biases(self, dim_out, name, trainable=True):
    24         shape = (dim_out, 1)
    25         initialBiases = tf.constant_initializer(np.zeros(shape))
    26         biases = tf.get_variable(
    27             initializer=initialBiases, shape=shape, trainable=True, name=name)
    28         if trainable:
    29             self.parameters.append(biases)
    30         return biases
    31     @staticmethod
    32     def truncated_normal(shape, stddev, mean=0.):
    33         rand_init = np.random.normal(loc=mean, scale=stddev, size=shape)
    34         inf_mask = rand_init < (mean - 2 * stddev)
    35         rand_init = rand_init * 
    36             np.abs(1 - inf_mask) + inf_mask * (mean - 2 * stddev)
    37         sup_mask = rand_init > (mean + 2 * stddev)
    38         rand_init = rand_init * 
    39             np.abs(1 - sup_mask) + sup_mask * (mean + 2 * stddev)
    40         return rand_init

     @staticmethod

    静态方法,类可以不用实例化就可以调用该方法,当然也可以实例化后调用。

    所以要注意这里前面几个函数用到的self.truncated_normal()并不是一开始我以为的tf.truncated_normal()这个正态分布函数(我就奇怪为什么是self.而不是tf.,名字一样的0.0)。

    那么这个函数传入参数为shape和stddev,形状和标准差。返回一个形状为shape的截断正态分布数组。

    其余函数,get_weights是得到shape=(dim_out, dim_in)的截断正太分布权重,get_4Dweights是得到shape=(filter_height, filter_width, in_channels, out_channels)的截断正态分布权重,get_biases是得到shape=(dim_out, 1)的初始零向量偏置。

    2. LSTMCell类

     1 class LSTMCell(TensorFlowTrainable):
     2     def __init__(self, num_units, **kwargs):
     3         super(LSTMCell, self).__init__()
     4         self._num_units = num_units  # 单元的个数
     5         self.w_i = self.get_weights(
     6             dim_in=2 * self._num_units, dim_out=self._num_units, name="w_i")  # 输入门权重
     7         self.w_f = self.get_weights(dim_in=2 * self._num_units, dim_out=self._num_units, name="w_f")  # 忘记门权重
     8         self.w_o = self.get_weights(dim_in=2 * self._num_units, dim_out=self._num_units, name="w_o")  # 输出门权重
     9         self.w_c = self.get_weights(dim_in=2 * self._num_units, dim_out=self._num_units, name="w_c")  # 数据输入权重
    10         self.b_i = self.get_biases(dim_out=self._num_units, name="b_i")  # 输入门偏重
    11         self.b_f = self.get_biases(dim_out=self._num_units, name="b_f")  # 忘记门偏重
    12         self.b_o = self.get_biases(dim_out=self._num_units, name="b_o")  # 输出门偏重
    13         self.b_c = self.get_biases(dim_out=self._num_units, name="b_c")  # 数据输入偏重
    14         self.c = [self.get_biases(dim_out=self._num_units, name="c", trainable=False)]  # 记忆细胞状态偏重
    15     def initialize_something(self, input):
    16         # 对输入做一定的变换,包括转置、展开、扩展为度等,并把数值初始化为1
    17         self.batch_size_vector = 1 + 0 * tf.expand_dims(tf.unstack(tf.transpose(input, [1, 0]))[0], 0)
    18         # 初始化
    19         self.h = [self.get_biases(dim_out=self._num_units, name="h", trainable=False) * self.batch_size_vector]
    20 
    21     def process(self, input, **kwargs):
    22         H = tf.concat([tf.transpose(input, perm=[1, 0]),self.h[-1]], 0)  # 将输入数据与上一时刻的记忆信息整合成一个新的输入
    23         i = tf.sigmoid(x=tf.add(tf.matmul(self.w_i, H), self.b_i))  # 经过输入门后的数据
    24         f = tf.sigmoid(x=tf.add(tf.matmul(self.w_f, H), self.b_f))  # 经过忘记门后的数据
    25         o = tf.sigmoid(x=tf.add(tf.matmul(self.w_o, H), self.b_o))  # 经过输出门后的数据
    26         c = f * self.c[-1] + i * tf.tanh(x=tf.add(tf.matmul(self.w_c, H), self.b_c))
    27         # 原代码:h = o * tf.tanh(x=self.c[-1])
    28         h = o * tf.tanh(x=self.c[-1])
    29         self.c.append(c)
    30         self.h.append(h)
    31 
    32     @property
    33     def features(self):
    34         return self.h[-1]  # 将最后一个的向量输出
    View Code

    tf.transpose(input, [dimension_1, dimenaion_2,..,dimension_n]): 这里[1, 0]就是把第0,1维交换位置了。

    tf.stack()这是一个矩阵拼接的函数,tf.unstack()则是一个矩阵分解的函数.

    stack把两个矩阵按某个轴拼接起来,与tf.concat有所区分。

    如拼接两个shape=(4, 3)的矩阵:

    concat拼接axis=0后的矩阵是shape=(8, 3),拼接axis=1后,shape=(4,6)

    stack拼接axis=0后的矩阵是shape=(2, 4, 3),拼接axis=1后的矩阵是shape=(4, 2, 3),拼接axis=0后的矩阵是shape=(4, 3, 1),

    input.shape=(m, n)

    H.shape=(2n, m)

    i.shape=(n, m)

    c.shape=(n, m)

    h.shape=(n, m)

    @property   装饰器

    用装饰器函数把 get/set 方法“装饰”成属性调用:
     1 class Student(object):
     2     def __init__(self, name, score):
     3         self.name = name
     4         self.__score = score
     5     def get_score(self):
     6         return self.__score
     7     def set_score(self, score):
     8         if score < 0 or score > 100:
     9             raise ValueError('invalid score')
    10         self.__score = score
    
    

    - >

     1 class Student(object):
     2     def __init__(self, name, score):
     3         self.name = name
     4         self.__score = score
     5     @property
     6     def score(self):
     7         return self.__score
     8     @score.setter
     9     def score(self, score):
    10         if score < 0 or score > 100:
    11             raise ValueError('invalid score')
    12         self.__score = score

    详见@property装饰器

    python super:

    Python: 你不知道的 super



    小结

    
    
    • 事实上,super 和父类没有实质性的关联。
    • super(cls, inst) 获得的是 cls 在 inst 的 MRO 列表中的下一个类。





















  • 相关阅读:
    利用Flask中的werkzeug.security模块加密
    logging
    python后端架构(转)
    访问一个网页的全过程
    微服务优缺点
    HTTP协议通信原理 与常见报错信息
    SSH与ansible 部署方法与核心模块简介
    linux 普通用户批量创建账户与密码
    三次握手与4次挥手简单说明
    sed 命令简介
  • 原文地址:https://www.cnblogs.com/valleyofwind/p/8630048.html
Copyright © 2020-2023  润新知