验证码&游戏外挂与图像识别——ANN

前面一篇写了关于简单的字符分离和特征提取,实际上,如果仅仅写个记牌器,那上篇识别出的特征直接用作牌面识别即可,根本无需进一步的工作——利用人工神经网络识别,但毕竟是为了完成前面的网页文章,还是写一下这个网络,因为验证码经处理后,可不会那么“老实”的每次都一模一样,我们需要的是神经网络来识别这些家伙。

 

从面向对象角度来说,人工神经网络可以向下划分为层,而层是由神经元构成的——神经元是构成人工神经网络的最基本单位,我们应该先实现它。神经元需要接受输入,无论它位于输入层、中间层或是输出层,同样也需要有输出,对于每一个输入,都需要对应一个权值,为了判断这个神经元处于激活还是抑制状态,我们需要一个函数来处理输入从而得到输出——这,就是一个神经元,据此,写出其代码:

Public Class Neuron

        '输入个数

        Protected m_inputsCount As Integer = 1

        '权值

        Protected weights As Double() = New Double(0) {}

        '激励函数

        Protected [function] As IActivationFunction = New SigmoidFunction()

        ' 加权的输入和 

        Protected sum As Double

        ' 神经输出值 

        Protected m_output As Double

        '随机数发生器

        Protected Shared rand As New Random()



        ' 输入总数属性 

        Public Property InputsCount() As Integer

            Get

                Return m_inputsCount

            End Get

            Set(ByVal value As Integer)

                m_inputsCount = Math.Max(1, value)

                weights = New Double(m_inputsCount - 1) {}

            End Set

        End Property



        ' 激活函数

        Public Property ActivationFunction() As IActivationFunction

            Get

                Return [function]

            End Get

            Set(ByVal value As IActivationFunction)

                [function] = value

            End Set

        End Property

        ' 输出值

        Public ReadOnly Property Output() As Double

            Get

                Return m_output

            End Get

        End Property

        ' 设置—获取权

        Default Public Property Item(ByVal index As Integer) As Double

            Get

                Return weights(index)

            End Get

            Set(ByVal value As Double)

                weights(index) = value

            End Set

        End Property



        ' 创建 

        Public Sub New()

        End Sub

        Public Sub New(ByVal inputs As Integer)

            Me.New(inputs, New SigmoidFunction())

        End Sub

        Public Sub New(ByVal inputs As Integer, ByVal [function] As IActivationFunction)

            Me.[function] = [function]

            InputsCount = inputs

        End Sub



        ' 计算神经输出值 

        Public Function Compute(ByVal input As Double()) As Double

            If input.Length <> m_inputsCount Then

                Throw New ArgumentException()

            End If

            sum = 0.0

            For i As Integer = 0 To m_inputsCount - 1

                ' 计算输入值加权和 

                sum += weights(i) * input(i)

            Next

            m_output = [function].Output(sum)

            Return m_output

        End Function



        ' 随机权值 

        Public Sub Randomize()

            For i As Integer = 0 To m_inputsCount - 1

                weights(i) = (rand.NextDouble())

            Next

        End Sub

    End Class
 
这就是一个神经元了。需要解释的是,我们用的S型函数是通过一个接口IActivationFunction来达到“传递”目的的。该接口的
    ''' <summary> 

    ''' 激励函数 —— 接口

    ''' </summary> 

    Public Interface IActivationFunction

        ' 计算函数值

        Function Output(ByVal input As Double) As Double

        ' 计算函数值微分

        Function OutputPrime(ByVal input As Double) As Double

        ' 计算函数值微分

        ' 使用函数值作为输入

        Function OutputPrime2(ByVal input As Double) As Double

    End Interface
 
接下来实现它们即可。
 
由神经元来构成层,实际上,从某种意义来说,层,也是一个神经,它们的代码极其相似,工作原理也基本相同:
Public Class Layer

        ' 输入个数

        Protected m_inputsCount As Integer

        '神经元个数

        Protected m_neuronsCount As Integer

        '层激励函数

        Protected [function] As IActivationFunction

        '神经

        Protected neurons As Neuron()

        '输出

        Protected m_output As Double()



        ' 输入个数

        Public Property InputsCount() As Integer

            Get

                Return m_inputsCount

            End Get

            Set(ByVal value As Integer)

                m_inputsCount = Math.Max(1, value)

                InitLayer()

            End Set

        End Property

        ' 神经个数

        Public Property NeuronsCount() As Integer

            Get

                Return m_neuronsCount

            End Get

            Set(ByVal value As Integer)

                m_neuronsCount = Math.Max(1, value)

                InitLayer()

            End Set

        End Property

        ' 激励函数

        Public Property ActivationFunction() As IActivationFunction

            Get

                Return [function]

            End Get

            Set(ByVal value As IActivationFunction)

                [function] = value

                For i As Integer = 0 To m_neuronsCount - 1

                    neurons(i).ActivationFunction = value

                Next

            End Set

        End Property

        ' 获取指定神经元

        Default Public ReadOnly Property Item(ByVal index As Integer) As Neuron

            Get

                Return neurons(index)

            End Get

        End Property

        ' 获取层输出

        Public ReadOnly Property Output() As Double()

            Get

                Return m_output

            End Get

        End Property





        ' 创建 

        Public Sub New()

            Me.New(1, 1, New SigmoidFunction())

        End Sub

        Public Sub New(ByVal neuronsCount As Integer)

            Me.New(neuronsCount, 1, New SigmoidFunction())

        End Sub

        Public Sub New(ByVal neuronsCount As Integer, ByVal inputsCount As Integer)

            Me.New(neuronsCount, inputsCount, New SigmoidFunction())

        End Sub

        Public Sub New(ByVal neuronsCount As Integer, ByVal inputsCount As Integer, ByVal [function] As IActivationFunction)

            Me.m_inputsCount = Math.Max(1, inputsCount)

            Me.m_neuronsCount = Math.Max(1, neuronsCount)

            Me.[function] = [function]

            InitLayer()

        End Sub



        ' 计算层输出

        Public Function Compute(ByVal input As Double()) As Double()

            For i As Integer = 0 To m_neuronsCount - 1

                m_output(i) = neurons(i).Compute(input)

            Next

            Return m_output

        End Function



        ' 随机化该层

        Public Sub Randomize()

            For Each neuron As Neuron In neurons

                neuron.Randomize()

            Next

        End Sub



        ' 初始化层

        Private Sub InitLayer()

            ' 创建层

            neurons = New Neuron(m_neuronsCount - 1) {}

            For i As Integer = 0 To m_neuronsCount - 1

                neurons(i) = New Neuron(m_inputsCount, [function])

            Next

            ' 分配输出数组

            m_output = New Double(m_neuronsCount - 1) {}

        End Sub



    End Class
 
只是层里面的激励函数我们另外实现,当然,用S型函数也不是不可以。。。。
 
接下来就是由层构成网络,还是上面那句话,网络啊,工作原理也和神经有点类似,代码基本是重复的罗列:
 
    ''' <summary> 
    ''' 网络——神经层的集合 
    ''' </summary> 
    <System.Serializable()> Public Class Network
        ' 输入个数
        Protected inputsCount As Integer
        '层数
        Protected m_layersCount As Integer
        '输出
        Protected m_output As Double()
        '层
        Protected layers As Layer()
        ' 层数
        Public ReadOnly Property LayersCount() As Integer
            Get
                Return m_layersCount
            End Get
        End Property
        ' 获取指定层
        Default Public ReadOnly Property Item(ByVal index As Integer) As Layer
            Get
                Return layers(index)
            End Get
        End Property
        ' 获取输出 
        Public ReadOnly Property Output() As Double()
            Get
                Return m_output
            End Get
        End Property
        Sub New()
        End Sub
        ' Constructors 
        Public Sub New(ByVal inputsCount As Integer, ByVal ParamArray neuronsCountPerLayer As Integer())
            Me.New(New SigmoidFunction(), inputsCount, neuronsCountPerLayer)
        End Sub
        Public Sub New(ByVal [function] As IActivationFunction, ByVal inputsCount As Integer, ByVal ParamArray neuronsCountPerLayer As Integer())
            Me.inputsCount = Math.Max(1, inputsCount)
            Me.m_layersCount = neuronsCountPerLayer.Length
            ' 创建层集合
            layers = New Layer(m_layersCount - 1) {}
            For i As Integer = 0 To m_layersCount - 1
                Dim m As Integer = 0
                If i = 0 Then m = inputsCount Else m = neuronsCountPerLayer(i - 1)
                layers(i) = New Layer(neuronsCountPerLayer(i), m, [function])
            Next
        End Sub
        ' 计算输出
        Public Function Compute(ByVal input As Double()) As Double()
            m_output = input
            For i As Integer = 0 To m_layersCount - 1
                m_output = layers(i).Compute(m_output)
            Next
            Return m_output
        End Function
        ' 随机化网络
        Public Sub Randomize()
            For Each layer As Layer In layers
                layer.Randomize()
            Next
        End Sub
    End Class
 
如此,就构成了这个神经网络。。。。。。
具体应用呢,我们需要另外定义一些属性、方法,来实现Back Propagation Learning:
 
属性:
1、学习速率
2、精度
3、动量
方法:
1、学习
2、计算误差
3、更新数据(各层权值直至各神经权值)
代码就是一些循环,不贴了。
 
 
有一点需要注意的,就是从图像中提取适当个数的特征可以加速学习和识别速度,但是太少就会影响网络的判断能力。
 
结合前面例子,我们可以提取垂直投影特征,来解决那些最幼稚的验证码:)有兴趣的话可以实现下。
 
一下是针对某网站的验证码图片处理后得到的一组学习图片采用随机特征提取后(图片大小14*18,提取特征40个,学习精度0.01),进行学习的数据:
 
学习次数     误差       Now.Second(当前时间的秒)
100  1.74766228723842   49
200  1.33293174843217   49
300  1.21399094064815   49
400  1.15740689778003   49
500  1.12433264177344   49
600  1.10263310876503   50
700  1.08728586760529   50
800  1.07582728337775   50
900  1.06688719120981   50
1000  1.05958542167266   50
1100  1.05308338562932   51
1200  1.04373940177007   51
1247  0.997537607633144   51

1300  0.608558811884911   51

1400  0.304230610883604   51

1500  0.212165790693552   51

1600  0.165892333507009   51

1700  0.138465048204805   52
1800  0.120396685718836   52

1900  0.107594382540998   52

1978  0.099921549727966   52
从上面数据可以看出,如果特征提取位置较好(这里是随机生成),则学习速度很快,几秒时间即可学习完成。
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于深度学习的FPS游戏角色检测源码+项目说明+游戏角色数据集.zip #### 开发思路与流程 **思路** CV领域的目标检测模型已经非常成熟,特别是yolov5系列 为什么不是用v6、v7?因为坑很多,而且效果不尽然好。 FPS游戏中,主要以击败敌方角色为目标,影响比赛成绩最主要的因素就是玩家的枪法。 使用深度学习的模型就可以对敌方角色进行准确定位,从而帮助玩家进行瞄准。而yolov5的预训练模型对于人物的识别已经很成熟。这时候只需要准备一定的数据样本,就可以实现不错效果。 **流程** **样本采集** 开发游戏中的截图代码`sample_util/collecting_data.py` 运行代码,进游戏后,会监听键盘。 截图会剪裁中心区域640X640(官方预训练模型的图片尺寸) 按`F`键将自动截图 按`~`键,将切换角色 保存图片至`sample/data/QF`目录和`sample/data/BW`目录 尽量选择**团队竞技**模式,游戏节奏会快很多,对不同的角色皮肤,不同的视角分别截图,我大概采集了500+保卫者和500+潜伏者图片 根据经验,图片样本主要不在于多,而是覆盖的角度、皮肤、光影等模式的分布广 ![](https://image-static.segmentfault.com/361/679/3616797238-63f74fbd825fc_fix732) **样本标注** .....
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清晨曦月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值