存档在 2017年1月

机器学习系列:递归神经网络

2017年1月23日

前言

BP神经网络,训练的时候,给定一组输入和输出,不断的对权值进行训练,使得输出达到稳定。但BP神经网络并不是适合所有的场景,并不真正的体现出某些场景的真正特点。回到经典的概率论问题,抛硬币问题,假设你已经抛了100次的,90次是正面的,10次是反面的,问现在继续在抛一次,出现正面的概率是多少?如果没有前面几次的经验,很正常的会认为再次出现正面的概率是50%,但由于我们之前有对这个进行了实验,即有了经验了,按照贝叶斯定律,出现正面的概率肯定会大于50%。BP神经网络也少了对前面结果的一种反馈。

常见,易懂的受到前位影响的算法,加法算法。十位的结果,所到个位结果的影响,因为可能有进位,同样,百位的结果所到十位的影响。

这种受到前位影响的算法非常的常见,而经典BP神经网络并不能很好的反映这种算法的特性,需要就经典的BP神经网络进行优化和改造,也就是引进前位,历史数据对网络的影响,使其具备时序性。通过历史数据的关联来推测后续的事情。

递归神经网络RNN

从前面加法算法的动态图中,对现有的 BP 神经网络进行改造,也就是加入前位的结果对于后续网络的影响。

这里把 BP 神经网络设计成上图的形式,很形象的揭示了递归神经网络的特点,前向的结果,作为下一个输入,影响下一个网络的结果。递归神经网络,在很多方向已经取得了很好的成果。而一种特殊的递归神经网络 Long Short Term 网络(LSTM),取到的结果最为璀璨,是这个方向的明星。

来看看LSTM的实现。

LSTM 网络

1997年 Hochreiter & Schmidhuber 提出了Long Short Term 网络,它是一种 RNN 的实现形式,在很多问题上,LSTM 取得了相当大的成功,在许多的领域上都有很好的成果。

最简单的 LSTM 网络:

把前位的输出结果当成后位的输入,经过 tanh 层,相当于扩充了原来BP神经网络的另一个输入。这样一次的进行训练。

在简化一点的方式如下图:

如果去掉 layer1 层,那么就是一个最简单的 BP神经网络了。这里引入了 layer1 层,使得经典的 BP 神经网络多了一个输入,layer_1 层在加法算法中,表示的是前一个输入就可以反映出加法算法的特性,从结构来看,这个 LSTM 的变形并不是非常的复杂,但现在就重要的就是如何计算出各个层次的增量,然后进行迭代了。

这里主要需要解决导数问题 python 的代码实现:

变量的更新:

其中 layer1delta 变量为两个变量的和:

完整的迭代过程在:

https://iamtrask.github.io/2015/11/15/anyone-can-code-lstm/

在递归神经网络中,跟经典的BP神经网络在结构上并没有太多的不同,最关键的点,还是在求解增量,进行迭代。

回头再想,如果仅仅用BP神经网络的算法能不能实现出加法算法,我觉得是可以的,但是速度和准确性不会有LSTM高。因此,LSTM的结构也是可以改进算法,不同的结构方式可以避免算法的很多缺陷。

更一般的LSTM结构:

算法的迭代过程在:

http://nicodjimenez.github.io/2014/08/08/lstm.html

https://github.com/nicodjimenez/lstm

算法跟BP神经网络没有太大的不同,但要注意的还是各个变量的增量和迭代问题。

递归神经网络的应用

递归神经网络跟BP神经网络,最大的不同是引进了时序,可以根据以往的数据来推测未来的事件。这是现在比较热门的一个方向。比较多的应用实在语音和文本的处理上,网上有相当多的关于递归神经网络的应用,比如写出像汪峰一样的歌词,默写唐诗,写冷段子等。但要写出像样的歌词和诗词,还需要做很多的处理,如果把递归神经网络应用在推荐系统里,也会得到不错的效果。

参考

C# 委托实例(跨窗体操作控件)

2017年1月23日

在C#里面却是可以不用自定义消息这么复杂的方法来实现跨窗体调用控件,C#有更好的办法就是委托。
效果描述:有两个窗体,FORM1(一个名为“打开form2”的button控件)和FORM2(一个名为“改变form1颜色“的button控件)。启动时,FORM1中点击button控件“打开form2””使FORM2显示出来。点击FORM2中的“改变form1颜色”后,Form1中颜色改变。

一、在Form2里面:
首先声明一个委托和委托实例
Form2类外

public delegate void ChangeFormColor(bool topmost);  

Form2类里

public event ChangeFormColor ChangeColor; 

Form2的按钮事件中调用委托

rivate void button1_Click(object sender, EventArgs e)  
        {  
            ChangeColor(true);//执行委托实例  
        }  

二、在Form1里面:
button控件“打开form2“的click事件中有下面的代码:

{  
    Form2 f = new Form2();  
    f.ChangeColor += new ChangeFormColor(f_ChangeColor);  
    f.Show();  
}  

f.ChangeColor += new ChangeFormColor(f_ChangeColor);
这句最关键,你输入到+=之后,按两下Tab,他会自动给你生成回调函数,如下:

void f_ChangeColor(bool topmost)  
        {  
            this.BackColor = Color.LightBlue;  
            this.Text = "改变成功";  
        }  

三、完整代码

using System;
using System.Drawing;
using System.Windows.Forms;

namespace 跨窗体调用控件
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Form2 f = new Form2();
            f.ChangeColor += new ChangeFormColor(f_ChangeColor);
            f.Show();
        }
        void f_ChangeColor(bool topmost)
        {
            this.BackColor = Color.LightBlue;
            this.Text = "改变成功";
        }
    }
}
using System;
using System.Windows.Forms;

namespace 跨窗体调用控件
{
    public delegate void ChangeFormColor(bool topmost);
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        public event ChangeFormColor ChangeColor;
        private void button1_Click(object sender, EventArgs e)
        {
            ChangeColor(true);//执行委托实例
        }
    }
}

apt-get update ,upgarde 和dist-upgrade

2017年1月23日

#sudo apt-get update 获得最近的软件包的列表;列表中包含一些包的信息,比如这个包是否更新过
#sudo apt-get dist-upgrade 如果这个包没有发布更新,就不管它;如果发布了更新,就把包下载到电脑上,并安装。

apt-get update 指令会同步使用者端和APT 伺服器的RPM 索引清单(package list),APT 伺服器的RPM 索引清单置于base 资料夹内,使用者端电脑取得base 资料夹内的bz2 RPM 索引清单压缩档后,会将其解压置放于/var/state/apt/lists/,而使用者使用apt-get install 或apt-get dist-upgrade 指令的时候,就会将这个资料夹内的资料和使用者端电脑内的RPM 资料库比对,如此一来就可以知道那些RPM 已安装、未安装、或是可以升级的。

这里提一下apt-get upgrade 与apt-get dist-upgrade的关系
由于包与包之间存在各种依赖关系。upgrade只是简单的更新包,不管这些依赖,它不和添加包,或是删除包。而dist-upgrade可以根据依赖关系的变化,添加包,删除包。

一般在运行upgrade或dist-upgrade之前,要运行update.

但是常常有人会问, upgrade和dist-upgrade有何不同,仔细查查,似乎大家对upgrade和dist-upgrade的解释都有点不同,在此也纪录自己的看法.

我认为apt-get upgrade和dist-upgrade的差别:

upgrade:系统将现有的Package升级,如果有相依性的问题,而此相依性需要安装其它新的Package或影响到其它Package的相依性时,此Package就不会被升级,会保留下来.

dist-upgrade:可以聪明的解决相依性的问题,如果有相依性问题,需要安装/移除新的Package,就会试着去安装/移除它. (所以通常这个会被认为是有点风险的升级)

apt-get upgrade 和 apt-get dist-upgrade 本质上是没有什么不同的。

只不过,dist-upgrade 会识别出当依赖关系改变的情形并作出处理,而upgrade对此情形不处理。

例如软件包 a 原先依赖 b c d,但是在源里面可能已经升级了,现在是 a 依赖 b c e。这种情况下,dist-upgrade 会删除 d 安装 e,并把 a 软件包升级,而 upgrade 会认为依赖关系改变而拒绝升级 a 软件包。

wordpress全站开启https具体过程

2017年1月19日

第一步:购买或者使用免费的SSL证书
免费的很多,比如沃通免费SSL申请地址:https://freessl.wosign.com 、还有一个重点提一下:Let’s Encrypt (开源项目)
一种是自动的,还有一种是国外的通过使用OPENSSL手动创建证书 下面说说具体步骤
生成命令:
openssl req -new -nodes -newkey rsa:2048 -keyout server.key -out server.csr
生成之后,csr文件内容copy给这些CA机构,自动给你一个crt。配合你刚刚生成的key,ok,完美。
拿到crt和key之后,我们开始在Nginx配置https:

# HTTP Server
server {
listen 80;
server_name www.kejianet.com kejianet.com;
rewrite ^ https://$server_name$request_uri permanent;
}

server {

listen 443 ssl http2;

ssl_certificate /usr/local/nginx/conf/vhost/ssl/kejianet.com.crt;
ssl_certificate_key /usr/local/nginx/conf/vhost/ssl/kejianet.com.key;
ssl_ciphers "CHACHA20:GCM:HIGH:!DH:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
#ssl_stapling on;
#ssl_stapling_verify on;
#resolver 8.8.8.8 8.8.4.4 valid=300s;
#resolver_timeout 5s;

如上,我们80端口的http全部301重定向到https。这样就不会对SEO产生什么不利的影响,百度站长明确说明:http网站和https当作同

一个站来处理,所以可以看到改版规则无https和http的区别,直接301完事!
第二步:把原网站http引用的图片和静态资源改成https
方法1:通过修改SQL即可。

方法2:通过找到当前主题下的 function.php 文件

function replacehttp($content){
if( is_ssl() ){
$content = str_replace('http://www.xxxxxx.com/inc/uploads', 'https://www.xxxxxx.com/inc/uploads', $content);
}
return $content;
}
add_filter('the_content', 'replacehttp');

注意:引用的CSS文件中也要一并修改。

第三步:wordpress后台改成https访问
wp-config.php文件中添加

define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);

Apache+ssl参考文献;http://blog.mimvp.com/2016/01/apache-httpsapache-http-access-go-to-https/

在linux中安装rpm版的mysql5.6的注意事项

2017年1月14日

建议先看看官方给出的安装文档 http://dev.mysql.com/doc/refman/5.7/en/linux-installation-rpm.html

安装完毕后会生成一个随机的root密码,密码保存在用户主目录下的.mysql_secret文件中

刚安装后使用/etc/init.d/下的名为mysql的脚本来启动mysql服务器 sh /etc/init.d/mysql start

启动后使用客户端连接,没修改root密码前只能使用 SET PASSWORD 命令

SET PASSWORD = PASSWORD('your_new_root_password');

Maven 打包成jar

2017年1月14日
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.5</version>
</plugin>

105409_IMZh_323105409_guLD_323

mysql中的 skip-name-resolve 问题

2017年1月10日

mysql连接很慢,登陆到服务器上查看服务器日志都是正常的,无可疑记录,登陆到mysql服务器上,查看下进程,发现有很多这样的连接:
218 | unauthenticated user | 192.168.10.6:44500 | NULL | Connect | NULL | login | NULL
219 | unauthenticated user | 192.168.10.6:44501 | NULL | Connect | NULL | login | NULL
……..

原因是由于mysql对连接的客户端进行DNS反向解析。
有2种解决办法:
1,把client的ip写在mysql服务器的/etc/hosts文件里,随便给个名字就可以了。
2,在 my.cnf 中加入 –skip-name-resolve 。
对于第一种方法比较笨,也不实用,那么 skip-name-resolve 选项可以禁用dns解析,但是,这样不能在mysql的授权表中使用主机名了,只能使用IP。
我理解mysql是这样来处理客户端解析过程的,
1,当mysql的client连过来的时候,服务器会主动去查client的域名。
2,首先查找 /etc/hosts 文件,搜索域名和IP的对应关系。
3,如果hosts文件没有,则查找DNS设置,如果没有设置DNS服务器,会立刻返回失败,就相当于mysql设置了skip-name-resolve参数,如果设置了DNS服务器,就进行反向解析,直到timeout。

所谓反向解析是这样的:
mysql接收到连接请求后,获得的是客户端的ip,为了更好的匹配mysql.user里的权限记录(某些是用hostname定义的)。
如果mysql服务器设置了dns服务器,并且客户端ip在dns上并没有相应的hostname,那么这个过程很慢,导致连接等待。

添加skip-name-resolve以后就跳过着一个过程了。