使用java实现CNN的实战

1、要实现CNN,其中包括 卷积、池化(下采样)、分类器、优化方法、分类器、反向传播

2、可以使用一个三维数组来表示一张图片(通道、行、列)

3、卷积,卷积的方式有三种:valid,full,same,在CNN中我们用到了两种:前向传播时,使用valid,反向传播时使  

full:假设我们的图片大小为 resourceImage:4*4,卷积核大小为  kernelSize:2*2,

    1> 前向传播时,valid 卷积的得到的resultImage:3*3 (4-2+1=3,假设stride为 1,pad :0)

    

case "valid" :
{
    resultImage = new double[inputImage.length-kernel.length+1][inputImage[0].length-kernel[0].length+1];
    for(int i=0;i<inputImage.length-kernel.length+1;i++)
    {
        for(int j=0;j<inputImage[0].length-kernel[0].length+1;j++)
        {
            int[] row={i,i+kernel.length-1};
            int[] col={j,j+kernel[0].length-1};
            double [][] regionImage= arroperation.copy2(inputImage,row,col);
            resultImage[i][j]=arroperation.product(regionImage,kernel);
        }
    }
    break;
}

其中 copy2 为我自己定义的函数,指的是复制二维数组指定区域的元素到一个新的二维数组

      product 也是我自己定义的函数,作用是:两个相同大小的二维数组对应位置成绩求和;

     2> 反向传播时,使用 full , (前向传播时 resourceImage:4*4, kernelSize:2*2, resultImage 3*3)

         反向传播,resourceImage:3*3, kernelSize:2*2, resultImage 4*4

我们可以使用补零的方式,使resourceImage 3*3 ------> tempImage 5*5

        然后使用valid 卷积方式, tempImage:4*4, kernelSize:2*2, resultImage 3*3

case "full":
{
    resultImage = new double[inputImage.length+inputImage[0].length-1][inputImage[0].length+kernel[0].length-1];
    double [][] tempImage=new double[inputImage.length+kernel.length-1][inputImage[0].length+kernel[0].length-1];
    for(int i=0;i<inputImage.length+2*kernel.length-2;i++)
    {
        for (int j=0;j<inputImage[0].length+2*kernel[0].length-2;j++)
        {
            tempImage[i][j]=0;
        }
    }
    for(int i=0;i<inputImage.length;i++)
    {
        for(int j=0;j<inputImage[0].length;j++)
        {
            tempImage[i+kernel.length-1][j+kernel[0].length-1]=inputImage[i][j];
        }
    }
    resultImage = convolutional(tempImage,kernel,"valid");
}

4、pooling 的方式有MAX ,Average , L1 等几种方式,在这里我只实现了,MAX 和 Average

     1> MAX 

case "MAX":
{
    for(int i=0;i<resultImage.length;i++)
    {
        for(int j=0;j<resultImage[0].length;j++)
        {
            int num=0;
            for(int m=0;m<poolingSize[0];m++)
            {
                for(int n=0;n<poolingSize[1];n++)
                {
                    tempArray[num]=resourceImage[i*poolingSize[0]+m][j*poolingSize[0]+n];
                    num=num+1;
                }
            }
            Arrays.sort(tempArray);
            resultImage[i][j]=tempArray[tempArray.length-1];

        }
    }
}
    break;

这里用到了一个java自带的一维数组排序的方法,可以自动使数组从小到大排列

Arrays.sort(tempArray);

2> Average

case "Average":
{
    double sum=0; // represent the sum of the element in subsampling area
    for(int i=0;i<resultImage.length;i++)
    {
        for(int j=0;j<resultImage[0].length;j++)
        {
            for(int m=0;m<poolingSize[0];m++)
            {
                for(int n=0;n<poolingSize[1];n++)
                {
                   sum=sum+resourceImage[i*poolingSize[0]+m][j*poolingSize[0]+n];
                }
            }
            resultImage[i][j]=sum/poolingSize[0]*poolingSize[1];

        }
    }
}
break;

在这里我想问一下,java 里有没有直接实现一位数组求和的方式,有的话,请留言告知我,谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

竖子敢尔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值