第九讲,权值初始化方法,损失函数

一,权值初始化

1.方差一致性原则:将每一层的方差都尽量控制在1左右

2.torch中提供了10种权值初始化方法:

在这里插入图片描述

  • 均匀分布
  • 正态分布
  • 常数分布
  • 单位矩阵初始化
  • Xavier均匀分布–》Xavier针对的是饱和激活函数
  • Xavier正态分布
  • 凯明均匀分布–》凯明针对的是非饱和激活函数
  • 凯明正态分布
  • 正交矩阵初始化
  • 系数矩阵初始化

3. nn.init.calculate_gain:计算激活函数的方差变化尺度

  • nonlinearity:激活函数名
  • param:激活函数的参数,比如Leaky Relu的negative_stop
  • 尺度计算方式:输入数据的方差/经过激活函数后的数据的方法
class MLP(nn.Module):
    def __init__(self, neural_num, layers):
        super(MLP, self).__init__()
        self.linears = nn.ModuleList([nn.Linear(neural_num, neural_num, bias=False) for i in range(layers)])
        self.neural_num = neural_num

    def forward(self, x):
        for (i, linear) in enumerate(self.linears):
            x = linear(x)
            # x = torch.relu(x) #添加非线性
            x = torch.tanh(x) #添加非线性

            print("layer:{}, std:{}".format(i, x.std()))
            if torch.isnan(x.std()):#如果模型标准差为nan了就停止前向传播
                print("output is nan in {} layers".format(i))
                break

        return x

    def initialize(self):
        for m in self.modules():
            if isinstance(m, nn.Linear):
                # nn.init.normal_(m.weight.data)    # normal: mean=0, std=1
                # nn.init.normal_(m.weight.data, std=np.sqrt(1/self.neural_num))    # normal: mean=0, std=1

                # a = np.sqrt(6 / (self.neural_num + self.neural_num))
                # tanh_gain = nn.init.calculate_gain('tanh')#计算增益
                # a *= tanh_gain #增益乘以尺度,
                # nn.init.uniform_(m.weight.data, -a, a)

                tanh_gain = nn.init.calculate_gain('tanh')  # 计算增益
                nn.init.xavier_uniform_(m.weight.data, gain=tanh_gain)

                # nn.init.normal_(m.weight.data, std=np.sqrt(2 / self.neural_num))
                # nn.init.kaiming_normal_(m.weight.data)


# flag = 0
flag = 1

if flag:
    layer_nums = 100
    neural_nums = 256
    batch_size = 16

    net = MLP(neural_nums, layer_nums)
    net.initialize()

    inputs = torch.randn((batch_size, neural_nums))  # normal: mean=0, std=1

    output = net(inputs)
    print(output)

二,损失函数:衡量模型输出与真实标签的差异

在这里插入图片描述

nn.CrossEntropyLoss:将NN.Logsoftmax()和nn.NLLLoss()结合,进行交叉熵计算

  • weight:各类别的loss设置权限
  • ignore_index:忽略某个类别
  • reduction:计算模式,默认是mean
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量
  • 交叉熵=信息熵+相对熵

nn.NLLLoss:实现负对数似然函数中负号的功能

  • weight:各类别的loss设置权限
  • ignore_index:忽略某个类别
  • reduction:计算模式,默认是mean
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.BCELoss:二分类交叉熵

  • weight:各类别的loss设置权限
  • ignore_index:忽略某个类别
  • reduction:计算模式,默认是mean
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量
  • 注意:输入为【0—1】

nn.BCEWithLogitLoss:集合sigmoid的二分类交叉熵

  • weight:各类别的loss设置权限
  • ignore_index:忽略某个类别
  • reduction:计算模式,默认是mean
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量
  • pos_weight:整样本权值—》正负样本均衡的作用

nn.L1Loss:计算inputs与target之差的绝对值

nn.MSELoss:计算intput与target之差的平方

  • reduction:计算模式
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.SmoothL1Loss:平滑的L1Loss

  • reduction:计算模式
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.PoissonNLLLoss:泊松分布的负对数似然损失函数

  • log_input:输入是否以对数形式决定计算公式
  • full:计算所有的loss,默认为False
  • eps:修正项,避免log(input)为nan

nn.KLDivLoss:计算KLD,kl散度,相对熵—》计算两个分布的相似性(距离)

  • reuuction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量
    • batchmean:维度求平均值
  • 需提前输入计算log-probabilities,通过nn.logsoftmax()可以实现

nn.MarginRankingLoss:计算两个向量之间的相似度,用于排序任务

  • margin:边界值,x1与x2之间的差异值。
  • reduction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.multiLabelMarginLoss:多标签边界损失函数

  • reduction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量
  • 不是多分类,是一个样本同时符合多个标签

nn.SoftMarginLoss:计算二分类的Logistic损失

  • reduction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.MultiLabelSoftMarginLoss:softmarginloss

  • weight:各类别的loss设置权值
  • reduction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.MultiMarginLoss:计算多分类的折页损失函数

  • p:可选1/2
  • weight:各类别的loss,设置权值
  • margin:边界值
  • reduction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.TripleMarginLoss:计算三元组损失,人脸验证中常用

  • p:范数的阶,默认为2
  • margin:边界值
  • reduction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.HingeEmbeddingLoss:计算两个输入的相似性,常用于非线性embedding和边监督学习

  • margin:边界值
  • reduction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.CosineEmbeddingLoss:采用 余弦相似度计算两个输入的相似性—》主要考虑方向上的差异

  • margin:可取值【-1,1】,推荐为【0, 0.5】
  • zero_infinity:无穷大的值或梯度置为0
  • reduction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量

nn.CTCLoss:计算CTC损失,解决时序类数据的分类

  • blank:blank label
  • zero_infinity:无穷大的值或梯度置为0
  • reduction:
    • none:逐个元素计算
    • sum:所有元素求和返回标量
    • mean:加权平均,返回标量
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 已知有n个整数,并且要将这些数分成若干个三个数一组的周期,如果不足一个周期,就在最后补上0。对于每个周期中第一个数的权值和等于a1 a[1 3] … …,求这三个数中权值最大的数的权值。如果最大权值在第一个数,输出’J’;如果最大权值在第二个数,输出’H’;如果最大权值在第三个数,输出’B’。 可以使用如下的代码来解决这个问题: ``` int n = // 输入n int a[n]; // 输入a[i] int max_val = 0; // 记录最大权值 char ans = ' '; // 记录答案 for (int i = 0; i < n; i += 3) { // 对于每一个周期,求出最大权值 int val = max(a[i], max(a[i+1], a[i+2])); // 如果当前周期最大权值更大,更新答案 if (val > max_val) { max_val = val; // 判断最大权值在哪个数 if (val == a[i]) ans = 'J'; else if (val == a[i+1]) ans = 'H'; else ans = 'B'; } } cout << ans << endl; // 输出答案 ``` 在上述代码中,我们首先使用一个for循环来遍历每一个周期。对于每一个周期,我们使用C++中的max函数来求出三个数中的最大值,然后将这个最大值与当前最大权值进 ### 回答2: 首先,我们将给定的n个整数以每三个数计算一个周期的方式进行分组,不足一个周期的数补0。然后,我们需要计算每个周期中第一个位置的数的权值和,即a1, a[1 3]等的和。 接下来,我们需要比较三个数的最大权值。首先,比较第一个数和第二个数的权值是否相等。如果它们的权值相等且大于第三个数的权值,则最大权值为第一个数;如果它们的权值相等且小于第三个数的权值,则最大权值为第三个数;如果它们的权值相等且等于第三个数的权值,则最大权值为第一个数和第三个数中的任意一个。如果第一个数和第二个数的权值不相等,则最大权值为它们中的较大值。 最后,根据最大权值的结果输出相应的字母。如果最大权值为第一个数,则输出’J’;如果最大权值为第二个数,则输出’H’;如果最大权值为第三个数,则输出’B’。 以上就是根据题意对给定的n个整数进行计算和比较得到最大权值,并输出相应字母的过程。 ### 回答3: 题目给出了n个整数,将它们分成若干个周期,每个周期包含3个数。如果不足一个周期,需要用0补齐。 要求是求出这些周期中,每个周期第一个数的权值和等于a1 a[1 3] … … 的情况下三个数的最大权值,并输出对应的字母。 首先,对于每个周期,我们可以计算权值和。权值和等于第一个数乘以1,第二个数乘以3,第三个数乘以9之和。 然后,我们需要遍历每个周期的权值和,找到最大的一个,记为max_weight。 接下来,我们需要确定最大权值在每个周期中对应的位置,即判断最大权值是第一个数、第二个数还是第三个数。 如果最大权值是第一个数,那么输出'J';如果最大权值是第二个数,输出'H';如果最大权值是第三个数,输出'B'。 最后,我们得到了答案。 以下是代码实现的伪代码: ``` max_weight = -1 # 初始化最大权值为-1 for i in range(n): a, b, c = 数组[i], 数组[i+1], 数组[i+2] # 取当前周期的三个数 total_weight = a * 1 + b * 3 + c * 9 # 计算权值和 if total_weight > max_weight: max_weight = total_weight if max_weight == 数组[0] * 1 + 数组[1] * 3 + 数组[2] * 9: 输出'J' elif max_weight == 数组[3] * 1 + 数组[4] * 3 + 数组[5] * 9: 输出'H' else: 输出'B' ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值