机器学习系列(2):初始化的一小步,网络性能的一大步

本文深入探讨了权重初始化在深度学习中的重要性,并对比了零初始化、随机初始化、He初始化和Xavier初始化等方法的优缺点及其对网络学习能力的影响。

 

 万事开头难?训练网络当然也不例外,哈哈没错,这里是机器学习系列第二篇,带你走进看似简单且容易被忽视的权重初始化,了解一下呗(清爽科普风),文末有小彩蛋哦

 

图片挂了,大家可以移步以下链接

https://mp.weixin.qq.com/s?__biz=MzU4NTY1NDM3MA==&mid=2247483750&idx=1&sn=9c5396026b218d53ceccf7d1d6bc3680&chksm=fd86086bcaf1817d23217da650fc3327ba02634b85577c0eb030da67570ff72b0c7e34c61a09&token=255604471&lang=zh_CN#rd

                                                              

                                                      01 初始化方式

1.1 导言: 

  • 在深度学习的训练中,权重的初始化起着重要的作用,如何选择合适的初始化方式,影响着网络的学习能力,今天我们就来看一下各种初始化方式有什么样的异同吧~

1.2:零初始化

Figure 1:三层前馈举例(图片来源知乎koala tree用户)

                                            

                                                Figure 2:三层前馈计算式(图片来源知乎koala tree用户)

  •  都初始化为零(矩阵、向量,下同),这种方式由于导致前馈过程具有对称性,反向传播也产生对称性,导致权重值一样,相当于降低了隐藏层神经元的个数,从而无法进行有效的学习。

  • 以一个三层网络为例:如下结构:

                                                            

    • 那么表达式就如下图所示:

    • 从上式可以看出,如果每个权重都一样,那么在多层网络中,从第二层开始,每一层的输入值都是相同的了也就是a1=a2=a3=....,那么就相当于一个输入了,那么反向传播算法最后得到的W和b也都相同,即对称的,就不能拟合任意输入到输出的映射了。

1.3:随机初始化

  • 初始化为随机值,b初始化为0,这种方式尽管b都为0,但由于W值不同,打破了对称性,可以有效学习,但是若网络深度很深,可能会产生梯度消失或梯度爆炸的问题,需要更好的方式。

  • 梯度消失:通常神经网络所用的激活函数是sigmoid函数,这个函数将负无穷到正无穷的输入映射到0和1之间,这个函数求导的结果是f′(x)=f(x)(1−f(x)),两个0到1之间的数相乘,得到的结果就会变得很小了。由于神经网络的反向传播是逐层对函数偏导相乘,因此当神经网络层数非常深的时候,最后一层产生的偏差就因为乘了很多的小于1的数而越来越小,非常接近0,从而导致层数比较浅的权重没有得到更新。

  • 那么什么是梯度爆炸呢?梯度爆炸就是由于初始化权值过大,前面层会比后面层变化的更快,就会导致权值越来越大,这就是梯度爆炸。

1.4:He initialization

  • 初始化为随机值后,再除以,b初始化为0,这种方式称为"he initialization",可以很好地控制每一层权重,使得其不会太大,从而有效降低梯度爆炸发生的概率,尤其对relu激活函数有效。

1.5:Xavier initialization

  • Xavier initialization和he initialization不同之处在于W除的数是 

                                                                                        

                                                      02 效果展示

2.1 假设我们要训练一个网络对下图(Figure 3)的红点和蓝点点进行二分类,运用不同的初始化方式,效果如下。

                                        

Figure 3:red dots and blue dots

 

  • 零初始化时,如下图,代价函数不变,分类正确率50%,相当于随机猜,所以网络不具备学习能力。

                                        

 

  • 随机初始化,效果提升,但由于初始化权重较大,性能还是不完美,分类正确率86%。

                                      

               

  • He initialization,效果比随机初始化提升,分类正确率达到96%

                                      

                                                                                     

                                                 03 python代码

3.1 本文相应的代码及资料已经以.ipynb文件和.pdf形式在github中给出。

 

 

点击【蓝字链接】,github传送门了解一下。

觉得有帮助的话别忘了star哦

 

人生若只如初见,是不拘一格又端庄优雅,不是所有对称都是完美,我愿意多爱你一点。

-by LSayhi的神经网络



 

 

逐步分析给出下列程序的计算公式,并给出公式中各个变量的具体含义:function [island_list, total_load] = improved_flood_alg(dg_locations, dg_powers, load_powers, adj_matrix, critical_loads) % 改进洪水算法 - 增强版(混合种子 + 模拟退火 + 自适应扰动) island_list = cell(size(dg_locations)); total_load = 0; for k = 1:length(dg_locations) dg_node = dg_locations(k); dg_power = dg_powers(k); reach = find_reachable_nodes_bfs(dg_node, adj_matrix); if isempty(reach) island_list{k} = dg_node; continue; end %—— 1. 多策略混合种子生成 —— seeds = generate_hybrid_seeds(dg_node, dg_power, load_powers, reach, critical_loads, adj_matrix); %—— 2. 模拟退火优化 —— best_nodes = seeds{1}; % 初始解 best_load = sum(load_powers(best_nodes)); % 模拟退火参数 T0 = 100.0; % 初始温度 alpha = 0.92; % 降温系数 nIter = 80; % 增加迭代次数 T = T0; current_nodes = best_nodes; current_load = best_load; for iter = 1:nIter %—— 自适应扰动规模 —— if iter <= nIter/3 % 早期:大步长探索 perturbation_size = min(5, length(reach)); elseif iter <= 2*nIter/3 % 中期:中等步长 perturbation_size = min(3, length(reach)); else % 后期:小步长精细调整 perturbation_size = min(2, length(reach)); end %—— 生成候选解 —— cand = adaptive_perturb(current_nodes, reach, load_powers, dg_power, perturbation_size); load_cand = sum(load_powers(cand)); %—— 模拟退火接受准则 —— delta_E = load_cand - current_load; if delta_E > 0 || (rand < exp(delta_E / T) && load_cand <= dg_power) current_nodes = cand; current_load = load_cand; % 更新全局最优 if current_load > best_load best_nodes = current_nodes; best_load = current_load; end end % 降温 T = T * alpha; end island_list{k} = best_nodes; total_load = total_load + best_load; end end function seeds = generate_hybrid_seeds(dg_node, dg_power, load_powers, reach, critical_loads, adj_matrix) % 生成混合种子解 seeds = cell(1, 3); % 种子1:贪心优先级解 scores = zeros(size(reach)); for i = 1:numel(reach) n = reach(i); scores(i) = (ismember(n, critical_loads) * 25) ... + load_powers(n)/25 ... - abs(n - dg_node)*0.03; end [~, idx] = sort(scores, 'descend'); sorted_nodes = reach(idx); current_nodes = dg_node; current_load = 0; for n = sorted_nodes if current_load + load_powers(n) <= dg_power current_nodes(end+1) = n; %#ok<AGROW> current_load = current_load + load_powers(n); end end seeds{1} = current_nodes; % 种子2:纯负荷容量优先解 [~, idx] = sort(load_powers(reach), 'descend'); sorted_by_load = reach(idx); current_nodes = dg_node; current_load = 0; for n = sorted_by_load if current_load + load_powers(n) <= dg_power current_nodes(end+1) = n; %#ok<AGROW> current_load = current_load + load_powers(n); end end seeds{2} = current_nodes; % 种子3:DFS启发式解 dfs_nodes = dfs_greedy_seed(dg_node, dg_power, load_powers, reach, adj_matrix); seeds{3} = dfs_nodes; % 选择最优种子作为初始解 loads = zeros(1, 3); for i = 1:3 loads(i) = sum(load_powers(seeds{i})); end [~, best_idx] = max(loads); seeds = {seeds{best_idx}}; % 只返回最优种子 end function dfs_nodes = dfs_greedy_seed(dg_node, dg_power, load_powers, reach, adj_matrix) % DFS启发式种子生成 dfs_nodes = dg_node; current_load = 0; visited = false(1, length(adj_matrix)); visited(dg_node) = true; % 从DG节点开始DFS stack = dg_node; while ~isempty(stack) && current_load < dg_power current = stack(end); stack(end) = []; % 找到未访问的邻居 neighbors = find(adj_matrix(current, :) & ~visited); for neighbor = neighbors if ismember(neighbor, reach) && ~visited(neighbor) if current_load + load_powers(neighbor) <= dg_power dfs_nodes(end+1) = neighbor; %#ok<AGROW> current_load = current_load + load_powers(neighbor); visited(neighbor) = true; stack(end+1) = neighbor; %#ok<AGROW> end end end end end function cand = adaptive_perturb(current_nodes, reach, load_powers, dg_power, perturbation_size) % 自适应扰动生成候选解 cand = current_nodes; % 扰动类型选择 if rand < 0.4 % 添加节点 available = setdiff(reach, cand); if ~isempty(available) num_add = min(perturbation_size, length(available)); to_add = available(randperm(length(available), num_add)); cand = unique([cand, to_add]); end elseif rand < 0.7 % 删除节点 if length(cand) > 1 num_remove = min(perturbation_size, length(cand)-1); to_remove = randperm(length(cand)-1, num_remove) + 1; % 不删除DG节点 cand(to_remove) = []; end else % 交换节点 if length(cand) > 1 && length(reach) > length(cand) num_swap = min(perturbation_size, length(cand)-1); for i = 1:num_swap if length(cand) > 1 % 随机选择个非DG节点进行交换 swap_idx = randi(length(cand)-1) + 1; available = setdiff(reach, cand); if ~isempty(available) cand(swap_idx) = available(randi(length(available))); end end end end end % 确保功率约束 while sum(load_powers(cand)) > dg_power && length(cand) > 1 % 移除负荷最大的非DG节点 non_dg = cand(2:end); [~, max_idx] = max(load_powers(non_dg)); cand(max_idx + 1) = []; end end
最新发布
09-05
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值