日撸java三百行day81-83

文章目录

  • 说明
  • CNN卷积神经网络
    • 1. 什么是CNN(CNN基础知识)
      • 1. 基本概念
      • 2.输入层
      • 3.卷积层
        • 3.1 图像
        • 3.2 卷积核
        • 3.3 偏置数
        • 3.4 滑动窗口步长
        • 3.5 特征图个数(特征图通道数或深度)
        • 3.6 边缘填充
        • 3.7 卷积过程例子
      • 4. 激活函数
      • 5. 池化层
      • 6.全连接层
    • 2. Day81 数据集读取与存储
      • 2.1 Dataset 数据集
      • 2.2 Size卷积尺寸类
      • 2.3 枚举类(LayerTypeEnum)
    • 3. Day82-83 数学操作
      • 3.1 MathUtils 类各个方法理解

说明

闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-CSDN博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata

CNN卷积神经网络

1. 什么是CNN(CNN基础知识)

1. 基本概念

CNN(Convolutional Neural Network卷积神经网络),是一种深度学习算法,它的结构灵感来自人类视觉系统的工作方式。卷积神经网络的整体一个架构是:输入层–>卷积层–>激活函数–>池化层–>全连接层–>输出层

2.输入层

这是网络的输入,也就是原始图像数据。这个图像一般是三维数据(而我在之前学习的ANN它其实是一个向量数据)

3.卷积层

这一层是CNN的核心,它会包含多个卷积核(或滤波器)。卷积核通过在输入图像上进行卷积运算来提取特征,并生成对应的特征图。

3.1 图像

  • 灰度图像:简单的理解就是灰度图像只有一个颜色通道
  • 彩色图像:简单的理解就是彩色图像包含红、绿、蓝(RGB)三个颜色通道的信息
    在这里插入图片描述

3.2 卷积核

对于灰度图像而言他的卷积核主要就是一个小的二维矩阵;对于彩色图形而言(简单的理解就是彩色图像包含红、绿、蓝(RGB)三个颜色通道的信息)他的卷积核主要就是一个小的三维张量。如下是一个彩色图像卷积核举例:
红色通道:
[ 100 150 200 50 75 100 25 30 40 ] \left[\begin {array}{c} 100 & 150 & 200 \\ 50 & 75 & 100 \\ 25 & 30 & 40 \\ \end{array}\right] 1005025150753020010040
绿色通道:
[ 200 180 160 140 120 100 80 60 40 ] \left[\begin {array}{c} 200 & 180 & 160 \\ 140 & 120& 100 \\ 80 & 60 & 40 \\ \end{array}\right] 200140801801206016010040
蓝色通道:
[ 30 60 90 120 150 180 210 240 255 ] \left[\begin {array}{c} 30 & 60 & 90 \\ 120 & 150 & 180 \\ 210 & 240 & 255 \\ \end{array}\right] 301202106015024090180255
彩色图像的每个通道都是一个 3x3 的矩阵,表示图像在每个像素位置的对应颜色强度。我们把这三个通道的信息合并起来,就得到了一个三维张量,形状为 (3, 3, 3)。并列的样子如图下所示(这里只是举例,而不是如下图所示)
在这里插入图片描述

3.3 偏置数

每个卷积核都可以设置相应的偏置项。在ANN中正向传播函数中也回设置偏置参数。设置偏置参数目的就是为了更好的捕捉图像的特征。

3.4 滑动窗口步长

卷积核在输入数据上滑动的步长,它决定了输出特征图的尺寸

如下是步长为1的卷积
在这里插入图片描述
如下是步长为2的卷积:
在这里插入图片描述

3.5 特征图个数(特征图通道数或深度)

特征图个数是由卷积层中使用的卷积核数量决定的。一个卷积层中使用了N个卷积核,那么这个卷积层就会生成N个输出特征图
如下图输入图像经过卷积层最后生成了6个特征图。
在这里插入图片描述

3.6 边缘填充

在进行卷积时,在输入数据的边界上添加额外的元素(一般是0,因为对原始数据基本没啥影响),以改变输出特征图的尺寸.一般边界的利用次数比较少,所以为了提高利用次数 就在外面加了一圈0,目的就是为了弥补边界缺失的信息。如下原始输入数据是5&5 但实际上矩阵的边界例如较少,所以在周围加上0就可以更好的通过原始数据捕捉特征。
在这里插入图片描述

3.7 卷积过程例子

  1. 输入的数据( h e i g h t ∗ w i d t h ∗ d e p t h i m a g e , 如下三维图所示 height*width*depth image,如下三维图所示 heightwidthdepthimage,如下三维图所示)为 7 ∗ 7 ∗ 3 7*7*3 773: 其中图形是进行了边缘填充,输入的数据是一个二维图像 7 ∗ 7 7*7 77,其中的depth=3代表图形的通道数
  2. 第一个卷积核为 3 ∗ 3 ∗ 3 3*3*3 333:也和输入数据一样是一个三维张量,具有高度、宽度和深度维度
  3. 偏置数b0=1
  4. A1的 3 ∗ 3 3*3 33矩阵 和卷积核B1 进行内积运算得值为:0;A2的 3 ∗ 3 3*3 33矩阵 和卷积核B2 进行内积运算得值为:2; A3的 3 ∗ 3 3*3 33矩阵 和卷积核B3 进行内积运算得值为:0;将三个相加0+2+0=2,再加上偏置1 即最后卷积的值为3,即C矩阵的第一个数。其他的计算都类似一样。矩阵移动步长为1
  5. 在图中可以知道,用了2个卷积核最后也会有2个特征图、

在这里插入图片描述在这里插入图片描述

4. 激活函数

文章链接

5. 池化层

对卷积后的特征图进行像下采样,以减小特征图的尺寸并保留重要的特征信息。类型有最大池化和平均池化。最大池化就是在窗口内选择最大的数值作为输出;平均池化就是在窗口内计算数值的平均值作为输出
在这里插入图片描述
在这里插入图片描述

6.全连接层

卷积层和池化层用于提取输入数据的局部特征;而全连接层将所有的特征数据映射到最终的输出类别上,用于分类、回归或其他任务。
在这里插入图片描述

2. Day81 数据集读取与存储

2.1 Dataset 数据集

这个是一个简单的数据集类,可用于表示和管理数据集中的数据实例。它通过读取文件中的数据并转换为 Instance 对象来初始化数据集。每个 Instance 对象包含属性数组和一个可选的标签值.

package machinelearing.cnn;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author: fulisha
 * @date: 2023/7/29 13:47
 * @description:
 */
public class Dataset {

    /**
     * All instances organized by a list.
     */
    private List<Instance> instances;

    /**
     * The label index.
     */
    private int labelIndex;

    /**
     * The max label (label start from 0).
     */
    private double maxLabel = -1;

    /**
     * The first constructor.
     */
    public Dataset() {
        labelIndex = -1;
        instances = new ArrayList<Instance>();
    }

    /**
     * The second constructor.
     * @param paraFilename The filename.
     * @param paraSplitSign Often comma.
     * @param paraLabelIndex Often the last column.
     */
    public Dataset(String paraFilename, String paraSplitSign, int paraLabelIndex) {
        instances = new ArrayList<Instance>();
        labelIndex = paraLabelIndex;

        File tempFile = new File(paraFilename);
        try {
            BufferedReader tempReader = new BufferedReader(new FileReader(tempFile));
            String tempLine;
            while ((tempLine = tempReader.readLine()) != null) {
                String[] tempDatum = tempLine.split(paraSplitSign);
                if (tempDatum.length == 0) {
                    continue;
                } // Of if

                double[] tempData = new double[tempDatum.length];
                for (int i = 0; i < tempDatum.length; i++) {
                    tempData[i] = Double.parseDouble(tempDatum[i]);
                }
                Instance tempInstance = new Instance(tempData);
                append(tempInstance);
            } // Of while
            tempReader.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Unable to load " + paraFilename);
            System.exit(0);
        }//Of try
    }// Of the second constructor

    /**
     * Append an instance.
     * @param paraInstance  The given record.
     */
    public void append(Instance paraInstance) {
        instances.add(paraInstance);
    }

    /**
     * Append an instance  specified by double values.
     */
    public void append(double[] paraAttributes, Double paraLabel) {
        instances.add(new Instance(paraAttributes, paraLabel));
    }

    /**
     * Getter.
     */
    public Instance getInstance(int paraIndex) {
        return instances.get(paraIndex);
    }

    /**
     * Getter.
     */
    public int size() {
        return instances.size();
    }

    /**
     * Getter.
     */
    public double[] getAttributes(int paraIndex) {
        return instances.get(paraIndex).getAttributes();
    }

    /**
     * Getter.
     */
    public Double getLabel(int paraIndex) {
        return instances.get(paraIndex).getLabel();
    }

    /**
     * Unit test.
     */
    public static void main(String args[]) {
        Dataset tempData = new Dataset("D:/sampledata/sampledata/src/data/train.format", ",", 784);
        Instance tempInstance = tempData.getInstance(0);
        System.out.println("The first instance is: " + tempInstance);
    }

    /**
     * An instance.
     */
    public class Instance {
        /**
         * Conditional attributes.
         */
        private double[] attributes;

        /**
         * Label.
         */
        private Double label;

        /**
         * The first constructor.
         */
        private Instance(double[] paraAttrs, Double paraLabel) {
            attributes = paraAttrs;
            label = paraLabel;
        }

        /**
         * The second constructor.
         */
        public Instance(double[] paraData) {
            if (labelIndex == -1)
            {
                // No label
                attributes = paraData;
            } else {
                label = paraData[labelIndex];
                if (label > maxLabel) {
                    // It is a new label
                    maxLabel = label;
                }

                if (labelIndex == 0) {
                    // The first column is the label
                    attributes = Arrays.copyOfRange(paraData, 1, paraData.length);
                } else {
                    // The last column is the label
                    attributes = Arrays.copyOfRange(paraData, 0, paraData.length - 1);
                }
            }
        }

        public double[] getAttributes() {
            return attributes;
        }

        public Double getLabel() {
            if (labelIndex == -1) {
                return null;
            }
            return label;
        }

        
        public String toString(){
            return Arrays.toString(attributes) + ", " + label;
        }
    }
}

输出结果:

The first instance is: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 0.0
  • Instance 是 Dataset 类的内部类,表示数据集中的单个数据实例
  • private List instances; 用于存储数据集中的所有数据实例
  • labelIndex 表示标签在数据实例属性数组中的索引位置。如果为 -1,则表示数据实例没有标签
  • maxLabel 记录数据集中出现的最大标签值
  • tempReader.readLine() 读一行数据
  • String 类的 split() 方法: 将字符串按照指定的分隔符拆分成一个字符串数组

2.2 Size卷积尺寸类

package machinelearing.cnn;

/**
 * @author: fulisha
 * @date: 2023/7/29 16:00
 * @description:
 */
public class Size {
    /**
     * Cannot be changed after initialization.
     */
    public final int width;

    /**
     * Cannot be changed after initialization.
     */
    public final int height;

    /**
     * The first constructor.
     * @param paraWidth The given width.
     * @param paraHeight The given height.
     */
    public Size(int paraWidth, int paraHeight) {
        width = paraWidth;
        height = paraHeight;
    }

    /**
     * Divide a scale with another one. For example (4, 12) / (2, 3) = (2, 4).
     * @param paraScaleSize The given scale size.
     * @return The new size.
     */
    public Size divide(Size paraScaleSize) {
        int resultWidth = width / paraScaleSize.width;
        int resultHeight = height / paraScaleSize.height;
        if (resultWidth * paraScaleSize.width != width
                || resultHeight * paraScaleSize.height != height) {
            throw new RuntimeException("Unable to divide " + this + " with " + paraScaleSize);
        }
        return new Size(resultWidth, resultHeight);
    }

    /**
     * Subtract a scale with another one, and add a value. For example (4, 12) -
     * (2, 3) + 1 = (3, 10).
     * @param paraScaleSize The given scale size.
     * @param paraAppend The appended size to both dimensions.
     * @return The new size.
     */
    public Size subtract(Size paraScaleSize, int paraAppend) {
        int resultWidth = width - paraScaleSize.width + paraAppend;
        int resultHeight = height - paraScaleSize.height + paraAppend;
        return new Size(resultWidth, resultHeight);
    }

    
    public String toString() {
        String resultString = "(" + width + ", " + height + ")";
        return resultString;
    }

    public static void main(String[] args) {
        Size tempSize1 = new Size(4, 6);
        Size tempSize2 = new Size(2, 2);
        System.out.println("" + tempSize1 + " divide " + tempSize2 + " = " + tempSize1.divide(tempSize2));

        System.out.printf("a");

        try {
            System.out.println(
                    "" + tempSize2 + " divide " + tempSize1 + " = " + tempSize2.divide(tempSize1));
        } catch (Exception ee) {
            System.out.println(ee);
        }

        System.out.println(
                "" + tempSize1 + " - " + tempSize2 + " + 1 = " + tempSize1.subtract(tempSize2, 1));
    }
}

  • divide方法(相除)
    该方法将当前对象的宽度和高度分别除以 paraScaleSize 对象的宽度和高度,得到 resultWidth 和 resultHeight。然后,验证计算后的宽高度是不是整数倍,若否抛出 RuntimeException 异常。反之返回。
  • subtract (相减)
    该方法将当前对象的宽度和高度分别减去 paraScaleSize 对象的宽度和高度,并在每个维度上添加 paraAppend 的值,得到 resultWidth 和 resultHeight,然后返回。

2.3 枚举类(LayerTypeEnum)

package machinelearing.cnn;

/**
 * @author: fulisha
 * @date: 2023/7/29 16:00
 * @description:
 */
public enum LayerTypeEnum {
    INPUT, CONVOLUTION, SAMPLING, OUTPUT;
}

3. Day82-83 数学操作

3.1 MathUtils 类各个方法理解

MathUtils 类中定义了一系列数学操作和矩阵运算的静态方法

package machinelearing.cnn;

import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

/**
 * @author: fulisha
 * @date: 2023/7/29 16:02
 * @description:
 */
public class MathUtils {

    /**
     * An interface for different on-demand operators.
     */
    public interface Operator extends Serializable {
        public double process(double value);
    }

    /**
     * The one-minus-the-value operator.
     */
    public static final Operator one_value = new Operator() {
        private static final long serialVersionUID = 3752139491940330714L;

        
        public double process(double value) {
            return 1 - value;
        }
    };

    /**
     * The sigmoid operator.
     */
    public static final Operator sigmoid = new Operator() {
        private static final long serialVersionUID = -1952718905019847589L;

        
        public double process(double value) {
            return 1 / (1 + Math.pow(Math.E, -value));
        }
    };

    /**
     * An interface for operations with two operators.
     */
    interface OperatorOnTwo extends Serializable {
        public double process(double a, double b);
    }

    /**
     * Plus.
     */
    public static final OperatorOnTwo plus = new OperatorOnTwo() {
        private static final long serialVersionUID = -6298144029766839945L;

        
        public double process(double a, double b) {
            return a + b;
        }
    };

    /**
     * Multiply.
     */
    public static OperatorOnTwo multiply = new OperatorOnTwo() {

        private static final long serialVersionUID = -7053767821858820698L;

        
        public double process(double a, double b) {
            return a * b;
        }
    };

    /**
     * Minus.
     */
    public static OperatorOnTwo minus = new OperatorOnTwo() {

        private static final long serialVersionUID = 7346065545555093912L;

        
        public double process(double a, double b) {
            return a - b;
        }
    };

    /**
     * Print a matrix
     */
    public static void printMatrix(double[][] matrix) {
        for (int i = 0; i < matrix.length; i++) {
            String line = Arrays.toString(matrix[i]);
            line = line.replaceAll(", ", "\t");
            System.out.println(line);
        }
        System.out.println();
    }

    /**
     * Rotate the matrix 180 degrees.
     */
    public static double[][] rot180(double[][] matrix) {
        matrix = cloneMatrix(matrix);
        int m = matrix.length;
        int n = matrix[0].length;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n / 2; j++) {
                double tmp = matrix[i][j];
                matrix[i][j] = matrix[i][n - 1 - j];
                matrix[i][n - 1 - j] = tmp;
            }
        }
        for (int j = 0; j < n; j++) {
            for (int i = 0; i < m / 2; i++) {
                double tmp = matrix[i][j];
                matrix[i][j] = matrix[m - 1 - i][j];
                matrix[m - 1 - i][j] = tmp;
            }
        }
        return matrix;
    }// Of rot180

    private static Random myRandom = new Random(2);

    /**
     * Generate a random matrix with the given size. Each value takes value in
     * [-0.005, 0.095].
     */
    public static double[][] randomMatrix(int x, int y, boolean b) {
        double[][] matrix = new double[x][y];
        // int tag = 1;
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                matrix[i][j] = (myRandom.nextDouble() - 0.05) / 10;
            }
        }
        return matrix;
    }

    /**
     * Generate a random array with the given length. Each value takes value in
     * [-0.005, 0.095].
     */
    public static double[] randomArray(int len) {
        double[] data = new double[len];
        for (int i = 0; i < len; i++) {
            //data[i] = myRandom.nextDouble() / 10 - 0.05;
            data[i] = 0;
        }
        return data;
    }

    /**
     * Generate a random perm with the batch size.
     */
    public static int[] randomPerm(int size, int batchSize) {
        Set<Integer> set = new HashSet<Integer>();
        while (set.size() < batchSize) {
            set.add(myRandom.nextInt(size));
        }
        int[] randPerm = new int[batchSize];
        int i = 0;
        for (Integer value : set) {
            randPerm[i++] = value;
        }
        return randPerm;
    }

    /**
     * Clone a matrix. Do not use it reference directly.
     */
    public static double[][] cloneMatrix(final double[][] matrix) {
        final int m = matrix.length;
        int n = matrix[0].length;
        final double[][] outMatrix = new double[m][n];

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                outMatrix[i][j] = matrix[i][j];
            }
        }
        return outMatrix;
    }

    /**
     * Matrix operation with the given operator on single operand.
     */
    public static double[][] matrixOp(final double[][] ma, Operator operator) {
        final int m = ma.length;
        int n = ma[0].length;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                ma[i][j] = operator.process(ma[i][j]);
            } // Of for j
        } // Of for i
        return ma;
    }// Of matrixOp

    /**
     * Matrix operation with the given operator on two operands.
     */
    public static double[][] matrixOp(final double[][] ma, final double[][] mb,
                                      final Operator operatorA, final Operator operatorB, OperatorOnTwo operator) {
        final int m = ma.length;
        int n = ma[0].length;
        if (m != mb.length || n != mb[0].length) {
            throw new RuntimeException("ma.length:" + ma.length + "  mb.length:" + mb.length);
        }

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                double a = ma[i][j];
                if (operatorA != null) {
                    a = operatorA.process(a);
                }
                double b = mb[i][j];
                if (operatorB != null) {
                    b = operatorB.process(b);
                }
                mb[i][j] = operator.process(a, b);
            }
        }
        return mb;
    }

    /**
     * Extend the matrix to a bigger one (a number of times).
     */
    public static double[][] kronecker(final double[][] matrix, final Size scale) {
        final int m = matrix.length;
        int n = matrix[0].length;
        final double[][] outMatrix = new double[m * scale.width][n * scale.height];

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                for (int ki = i * scale.width; ki < (i + 1) * scale.width; ki++) {
                    for (int kj = j * scale.height; kj < (j + 1) * scale.height; kj++) {
                        outMatrix[ki][kj] = matrix[i][j];
                    }
                }
            }
        }
        return outMatrix;
    }

    /**
     * Scale the matrix.
     */
    public static double[][] scaleMatrix(final double[][] matrix, final Size scale) {
        int m = matrix.length;
        int n = matrix[0].length;
        final int sm = m / scale.width;
        final int sn = n / scale.height;
        final double[][] outMatrix = new double[sm][sn];
        if (sm * scale.width != m || sn * scale.height != n) {
            throw new RuntimeException("scale matrix");
        }
        final int size = scale.width * scale.height;
        for (int i = 0; i < sm; i++) {
            for (int j = 0; j < sn; j++) {
                double sum = 0.0;
                for (int si = i * scale.width; si < (i + 1) * scale.width; si++) {
                    for (int sj = j * scale.height; sj < (j + 1) * scale.height; sj++) {
                        sum += matrix[si][sj];
                    }
                }
                outMatrix[i][j] = sum / size;
            }
        }
        return outMatrix;
    }

    /**
     * Convolution full to obtain a bigger size. It is used in back-propagation.
     */
    public static double[][] convnFull(double[][] matrix, final double[][] kernel) {
        int m = matrix.length;
        int n = matrix[0].length;
        final int km = kernel.length;
        final int kn = kernel[0].length;
        final double[][] extendMatrix = new double[m + 2 * (km - 1)][n + 2 * (kn - 1)];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                extendMatrix[i + km - 1][j + kn - 1] = matrix[i][j];
            }
        }
        return convnValid(extendMatrix, kernel);
    }

    /**
     * Convolution operation, from a given matrix and a kernel, sliding and sum
     * to obtain the result matrix. It is used in forward.
     */
    public static double[][] convnValid(final double[][] matrix, double[][] kernel) {
        // kernel = rot180(kernel);
        int m = matrix.length;
        int n = matrix[0].length;
        final int km = kernel.length;
        final int kn = kernel[0].length;
        int kns = n - kn + 1;
        final int kms = m - km + 1;
        final double[][] outMatrix = new double[kms][kns];

        for (int i = 0; i < kms; i++) {
            for (int j = 0; j < kns; j++) {
                double sum = 0.0;
                for (int ki = 0; ki < km; ki++) {
                    for (int kj = 0; kj < kn; kj++) {
                        sum += matrix[i + ki][j + kj] * kernel[ki][kj];
                    }
                }
                outMatrix[i][j] = sum;

            }
        }
        return outMatrix;
    }

    /**
     * Convolution on a tensor.
     */
    public static double[][] convnValid(final double[][][][] matrix, int mapNoX,
                                        double[][][][] kernel, int mapNoY) {
        int m = matrix.length;
        int n = matrix[0][mapNoX].length;
        int h = matrix[0][mapNoX][0].length;
        int km = kernel.length;
        int kn = kernel[0][mapNoY].length;
        int kh = kernel[0][mapNoY][0].length;
        int kms = m - km + 1;
        int kns = n - kn + 1;
        int khs = h - kh + 1;
        if (matrix.length != kernel.length) {
            throw new RuntimeException("length");
        }
        final double[][][] outMatrix = new double[kms][kns][khs];
        for (int i = 0; i < kms; i++) {
            for (int j = 0; j < kns; j++) {
                for (int k = 0; k < khs; k++) {
                    double sum = 0.0;
                    for (int ki = 0; ki < km; ki++) {
                        for (int kj = 0; kj < kn; kj++) {
                            for (int kk = 0; kk < kh; kk++) {
                                sum += matrix[i + ki][mapNoX][j + kj][k + kk]
                                        * kernel[ki][mapNoY][kj][kk];
                            }
                        }
                    }
                    outMatrix[i][j][k] = sum;
                }
            }
        }
        return outMatrix[0];
    }

    /**
     * The sigmod operation.
     */
    public static double sigmod(double x) {
        return 1 / (1 + Math.pow(Math.E, -x));
    }

    /**
     * Sum all values of a matrix.
     */
    public static double sum(double[][] error) {
        int m = error.length;
        int n = error[0].length;
        double sum = 0.0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                sum += error[i][j];
            }
        }
        return sum;
    }

    /**
     * Ad hoc sum.
     */
    public static double[][] sum(double[][][][] errors, int j) {
        int m = errors[0][j].length;
        int n = errors[0][j][0].length;
        double[][] result = new double[m][n];
        for (int mi = 0; mi < m; mi++) {
            for (int nj = 0; nj < n; nj++) {
                double sum = 0;
                for (int i = 0; i < errors.length; i++)
                    sum += errors[i][j][mi][nj];
                result[mi][nj] = sum;
            }
        }
        return result;
    }

    /**
     * Get the index of the maximal value for the final classification.
     */
    public static int getMaxIndex(double[] out) {
        double max = out[0];
        int index = 0;
        for (int i = 1; i < out.length; i++) {
            if (out[i] > max) {
                max = out[i];
                index = i;
            }
        }
        return index;
    }
}

  • Operator 接口
    可以对单个值进行操作的操作符,接口中只有一个抽象方法 double process(double value)
  • one_value操作符
    实现了 Operator 接口的匿名内部类,代表 “1 - value” 的操作符,它实现了 process 方法,用于返回 1 - value 的结果
  • sigmoid操作符
    实现了 Operator 接口的匿名内部类,代表 Sigmoid 函数的操作符,它实现了 process 方法,用于返回 Sigmoid 激活函数的结果
  • OperatorOnTwo 接口
    可以对两个值进行操作的操作符,接口中只有一个抽象方法 double process(double a, double b)
  • plus 操作符
    实现了 OperatorOnTwo 接口的匿名内部类,代表加法操作符,它实现了 process 方法,用于返回 a + b 的结果
  • multiply操作符
    实现了 OperatorOnTwo 接口的匿名内部类,代表乘法操作符,它实现了 process 方法,用于返回 a * b 的结果
  • minus 操作符
    实现了 OperatorOnTwo 接口的匿名内部类,代表减法操作符,它实现了 process 方法,用于返回 a - b 的结果
  • printMatrix(double[][] matrix)方法
    打印一个二维矩阵
  • rot180(double[][] matrix) 方法
    将一个二维矩阵逆时针旋转180度
  • randomMatrix(int x, int y, boolean b) 方法
    生成一个指定大小的随机矩阵
  • randomArray(int len)方法
    生成一个指定长度的随机数组
  • randomPerm(int size, int batchSize)方法
    生成一个指定大小的随机排列(size 是排列的范围,batchSize 是排列的大小)
  • cloneMatrix方法
    克隆矩阵
  • matrixOp(final double[][] ma, Operator operator)方法
    对单个操作数执行矩阵操作。matrixOp方法用于对输入矩阵ma中的每个元素应用给定的operator运算符,并返回执行后的结果
  • matrixOp(final double[][] ma, final double[][] mb, final Operator operatorA, final Operator operatorB, OperatorOnTwo operator)
    对两个操作数执行矩阵操作。使用两个指定的operatorA和operatorB对两个矩阵的元素执行操作、
  • kronecker(final double[][] matrix, final Size scale)
    扩展矩阵到更大的大小。对给定的矩阵 matrix 进行 Kronecker 乘积,并根据指定的 scale 尺寸进行缩放。
    代码的一个举例过程:
    m a t r i x = [ 1 2 3 4 ] matrix = \left[\begin {array}{c} 1 & 2 \\ 3 & 4 \\ \end{array}\right] matrix=[1324]
    scale = Size(2, 3)
    矩阵的大小: (4,6): m = 2 * 2 = 4,n = 2 * 3 = 6
    matrix[0][0] = 1,对他进行填充:
    [ 1 1 1 1 1 1 ] \left[\begin {array}{c} 1 & 1& 1 \\ 1 & 1& 1\\ \end{array}\right] [111111]
    matrix[0][1] = 2 进行填充
    [ 2 2 2 2 2 2 ] \left[\begin {array}{c} 2 & 2& 2 \\ 2 & 2& 2\\ \end{array}\right] [222222]
    同理其他最后得到的矩阵:
    [ 1 1 1 2 2 2 1 1 1 2 2 2 3 3 3 4 4 4 3 3 3 4 4 4 ] \left[\begin {array}{c} 1 & 1& 1 &2 & 2& 2 \\ 1 & 1& 1 &2 & 2& 2\\ 3 & 3& 3 &4 & 4& 4\\ 3 & 3& 3 &4 & 4& 4\\ \end{array}\right] 113311331133224422442244

kronecker积举例一个计算过程:
A矩阵:
[ a 11 a 12 a 21 a 22 ] \left[\begin {array}{c} a_{11} & a_{12} \\ a_{21} & a_{22} \\ \end{array}\right] [a11a21a12a22]
B矩阵:
[ b 11 b 12 b 21 b 22 ] \left[\begin {array}{c} b_{11} & b_{12} \\ b_{21} & b_{22} \\ \end{array}\right] [b11b21b12b22]
A ⊗ B = C A ⊗ B=C AB=C的矩阵大小为 (m * p)x(n * q),其中m 和 n 是矩阵 A 的行数和列数,p 和 q 是矩阵 B 的行数和列数。故上面C矩阵是一个4x4的矩阵
其中 c 11 = a 11 ∗ B = [ a 11 ∗ b 11 a 11 ∗ b 12 a 11 ∗ b 21 a 11 ∗ b 22 ] c_{11}=a_{11}*B=\left[\begin {array}{c} a_{11}*b_{11}& a_{11}*b_{12} \\ a_{11}*b_{21} & a_{11}*b_{22} \\ \end{array}\right] c11=a11B=[a11b11a11b21a11b12a11b22]
其中 c 12 = a 12 ∗ B = [ a 12 ∗ b 11 a 12 ∗ b 12 a 12 ∗ b 21 a 12 ∗ b 22 ] c_{12}=a_{12}*B=\left[\begin {array}{c} a_{12}*b_{11}& a_{12}*b_{12} \\ a_{12}*b_{21} & a_{12}*b_{22} \\ \end{array}\right] c12=a12B=[a12b11a12b21a12b12a12b22]
以此类推,故最后的结果为:
C = [ a 11 ∗ b 11 a 11 ∗ b 12 a 12 ∗ b 11 a 12 ∗ b 12 a 11 ∗ b 21 a 11 ∗ b 22 a 12 ∗ b 21 a 12 ∗ b 22 a 21 ∗ b 11 a 21 ∗ b 12 a 22 ∗ b 11 a 22 ∗ b 12 a 21 ∗ b 21 a 21 ∗ b 22 a 22 ∗ b 21 a 22 ∗ b 22 ] C= \left[\begin {array}{c} a_{11}*b_{11}& a_{11}*b_{12} & a_{12}*b_{11}& a_{12}*b_{12} \\ a_{11}*b_{21} & a_{11}*b_{22} & a_{12}*b_{21} & a_{12}*b_{22} \\ a_{21}*b_{11}& a_{21}*b_{12} & a_{22}*b_{11}& a_{22}*b_{12} \\ a_{21}*b_{21} & a_{21}*b_{22} & a_{22}*b_{21} & a_{2 2}*b_{22} \\ \end{array}\right] C= a11b11a11b21a21b11a21b21a11b12a11b22a21b12a21b22a12b11a12b21a22b11a22b21a12b12a12b22a22b12a22b22

  • scaleMatrix(final double[][] matrix, final Size scale)
    用于缩放矩阵的方法,即将原始矩阵按照指定的大小比例进行缩放。将原始矩阵缩小到一个更小的尺寸,通过将相邻元素的值进行平均来得到新的缩放后的矩阵
    例如:
    m a t r i x = [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ] matrix = \left[\begin {array}{c} 1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & 14 & 15 & 16 \\ \end{array}\right] matrix= 15913261014371115481216
    设置的size: Size scale = new Size(2, 2);
    经过scaleMatrix方法后,输出的矩阵大小为(2,2);为:

    • 对于第一行第一列的元素:计算原始矩阵中小区域 {(0, 0), (0, 1), (1, 0), (1, 1)} 内元素的平均值:(1 + 2 + 5 + 6) / 4 = 3.5,将其赋值给 scaledMatrix[0][0]。
    • 最终的矩阵
      [ 3.5 5.5 11.5 13.5 ] \left[\begin {array}{c} 3.5 & 5.5 \\ 11.5 & 13.5\\ \end{array}\right] [3.511.55.513.5]
  • convnFull(double[][] matrix, final double[][] kernel)
    在原始矩阵的边缘进行零填充,再进行卷积操作。
    举例:
    原始矩阵matrix
    m a t r i x = [ 1 2 3 4 5 6 7 8 9 10 11 12 ] matrix = \left[\begin {array}{c} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ 10 & 11 & 12 \\ \end{array}\right] matrix= 147102581136912
    边缘进行零填充:
    e x t e n d M a t r i x = [ 0 0 0 0 0 0 1 2 3 0 0 4 5 6 0 0 7 8 9 0 0 10 11 12 0 0 0 0 0 0 ] extendMatrix= \left[\begin {array}{c} 0 & 0 & 0 & 0& 0 & \\ 0 &1 & 2 & 3 & 0 \\ 0 & 4 & 5 & 6 & 0 \\ 0 & 7 & 8 & 9 & 0 \\ 0 & 10 & 11 & 12 & 0 \\ 0 & 0 & 0 & 0& 0 & \\ \end{array}\right] extendMatrix= 000000014710002581100369120000000
    再调用convnValid进行卷积操作:
    k e r n e l (卷积核) = [ 0 1 2 3 ] kernel(卷积核)= \left[\begin {array}{c} 0& 1 \\ 2 & 3 \\ \end{array}\right] kernel(卷积核)=[0213]
    最后的结果为(内积):
    o u t M a t r i x = [ 3 8 13 6 13 25 31 12 25 43 49 18 7 8 9 0 ] outMatrix= \left[\begin {array}{c} 3 & 8 & 13 & 6 \\ 13 & 25 & 31 & 12 \\ 25 & 43 & 49 & 18 \\ 7 & 8 & 9 & 0 \\ \end{array}\right] outMatrix= 3132578254381331499612180

  • convnValid(final double[][] matrix, double[][] kernel)
    在二维矩阵matrix上进行卷积操作,卷积核为kernel,因此输出的矩阵大小会缩小。

  • convnValid(final double[][][][] matrix, int mapNoX,double[][][][] kernel, int mapNoY)
    用于在四维张量上进行卷积操作,在这里,四维张量类似于多个特征图(Feature Map)的集合,这些特征图通常用于卷积神经网络中的不同层。
    在这里插入图片描述

  • sum(double[][] error)
    用于计算二维矩阵中所有元素的总和

  • sum(double[][][][] errors, int j)
    这个方法通常用于在卷积层后、激活函数或池化层后,对多个特征图进行逐位置的求和操作,以得到更加丰富的特征表示。errors是一个四维数组,表示包含多个特征图(Feature Map)的集合(第一维表示特征图的深度或数量,第二维表示特征图的索引,第三维和第四维表示特征图的行和列)

  • getMaxIndex
    用于从给定数组中找到最大值,并返回最大值的索引位置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/63055.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

bagging集成与boosting集成的区别是什么?

bagging集成与boosting集成的区别 区别一:数据方面 Bagging&#xff1a;对数据进行采样训练; Boosting&#xff1a;根据前一轮学习结果调整数据的重要性。 区别二:投票方面 Bagging&#xff1a;所有学习器平权投票; Boosting&#xff1a;对学习器进行加权投票。 区别三:…

Maven-生命周期及命令

关于本文 ✍写作原因 之前在学校学习的时候&#xff0c;编写代码使用的项目都是单体架构&#xff0c;导入开源框架依赖时只需要在pom.xml里面添加依赖&#xff0c;点一下reload按钮即可解决大部分需求&#xff1b;但是在公司使用了dubbo微服务架构之后发现只知道使用reload不足…

网络安全--原型链污染

目录 1.什么是原型链污染 2.原型链三属性 1&#xff09;prototype 2)constructor 3)__proto__ 4&#xff09;原型链三属性之间关系 3.JavaScript原型链继承 1&#xff09;分析 2&#xff09;总结 3)运行结果 4.原型链污染简单实验 1&#xff09;实验一 2&#xff0…

回归预测 | MATLAB实现POA-CNN-LSTM鹈鹕算法优化卷积长短期记忆神经网络多输入单输出回归预测

回归预测 | MATLAB实现POA-CNN-LSTM鹈鹕算法优化卷积长短期记忆神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现POA-CNN-LSTM鹈鹕算法优化卷积长短期记忆神经网络多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现POA-CNN…

【Linux】多路转接 -- select函数

文章目录 1. 认识select函数2. select函数原型3. socket就绪条件4. select工作流程5. select服务器6. select的优缺点 首先我们要了解一下&#xff0c;什么是多路转接&#xff1f; 多路转接也叫多路复用&#xff0c;是一种用于管理多个IO通道的技术。它能实现同时监听和处理多个…

《动手学深度学习》优化算法学习习题

优化算法 梯度下降类 小批量随机梯度下降&#xff0c;通过平均梯度来减小方差 动量法 基础 泄露平均法&#xff1a;用来取代梯度的计算 β \beta β这个参数控制了取多久时间的平均值 上述推理构成了”加速”梯度方法的基础&#xff0c;例如具有动量的梯度。 在优化问题…

直播招聘小程序解决方案

项目开发愿景 介绍工作拿佣金&#xff0c;Boss直播现真身。做为直播招聘的新平台&#xff0c;让求职和招聘变得更简单&#xff01;企业发布招聘视频&#xff0c;展现公司环境与实力&#xff0c;开通会员可以直播招聘、在线面试功能&#xff1b;求职者刷视频可以刷到工作…

day5 6 7-牛客67道剑指offer-JZ43、45、49、50、51、52、53、55、79、数组中只出现一次的数字

文章目录 1. JZ43 整数中1出现的次数&#xff08;从1到n整数中1出现的次数&#xff09;2. JZ45 把数组排成最小的数3. JZ49 丑数最小堆三指针法 动态规划 4. JZ50 第一个只出现一次的字符5. JZ51 数组中的逆序对6. JZ52 两个链表的第一个公共结点迭代递归 7. JZ53 数字在升序数…

想在金融界拥有一席之地吗—社科院杜兰大学金融管理硕士助你圆梦

追求高学历是为了什么&#xff1f;一纸证书吗&#xff1f;显然并非如此&#xff0c;只有读过研的人才有话语权。在上升一个平台后&#xff0c;你必然会发现&#xff0c;更高学历得到的不止是一张文凭。而是更大的平台、更广阔的视野、更包容的环境&#xff0c;更多样的文化。最…

机器学习笔记之优化算法(九)收敛速度的简单认识

机器学习笔记之优化算法——收敛速度的简单认识 引言收敛速度的判别标准 Q \mathcal Q Q-收敛速度 R \mathcal R R-收敛速度关于算法复杂度与收敛速度 引言 本节对收敛速度简单介绍。 收敛速度的判别标准 我们之前几节介绍了线搜索方法 ( Line Search Method ) (\text{Line …

从小白到数据库达人!Mysql优化让你的社招面试无往不利!

大家好&#xff0c;我是小米&#xff0c;在这个美好的时刻又迎来了我们的技术小窝。今天&#xff0c;我们要聊一聊一个在数据库领域中无比重要的话题 —— Mysql 优化&#xff01;是不是感觉很兴奋呢&#xff1f;废话不多说&#xff0c;让我们直接进入今天的主题。 背景知识 …

输入框长度在XSS测试中如何绕过字符长度限制

大家好&#xff0c;这是我编写的第一篇文章&#xff0c;之所以会分享这个故事&#xff0c;是因为我花了几个晚上的时间&#xff0c;终于找到了解决某个问题的方法。故事如下&#xff1a; 几个月前&#xff0c;我被邀请参加一个非公共的漏洞悬赏项目&#xff0c;在初期发现了一些…

动态规划(二)

一、线性DP 1.1数字三角形 #include<iostream> #include<algorithm>using namespace std;const int N 510,INF 1e9;int n; int a[N][N]; int f[N][N];int main() {scanf("%d",&n);for(int i 1;i < n;i ){for(int j 1;j < i; j )scanf(&qu…

大数据之Hadoop(一)

目录 一、准备三台服务器 二、虚拟机间配置免密登录 三、安装JDK 四、关闭防火墙 五、关闭安全模块SELinux 六、修改时区和自动时间同步 一、准备三台服务器 我们先准备三台服务器&#xff0c;可以通过虚拟机的方式创建&#xff0c;也可以选择云服务器。 关于如何创建虚…

神经网络的搭建与各层分析

为什么去西藏的人都会感觉很治愈 拉萨的老中医是这么说的 缺氧脑子短路&#xff0c;很多事想不起来&#xff0c;就会感觉很幸福 一、卷积层 解释&#xff1a;卷积层通过卷积操作对输入数据进行处理。它使用一组可学习的滤波器&#xff08;也称为卷积核或特征检测器&#xff09…

Java on Azure Tooling 6月更新|标准消费和专用计划及本地存储账户(Azurite)支持

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Java on Azure 工具的六月更新。在本次更新中&#xff0c;我们将介绍 Azure Spring Apps 标准消费和专用计划支持以及本地存储账户&…

AI 绘画Stable Diffusion 研究(四)sd文生图功能详解(上)

大家好&#xff0c;我是风雨无阻。 通过前面几篇AI 绘画Stable Diffusion 研究系列的介绍&#xff0c;我们完成了Stable Diffusion整合包的安装、模型ControlNet1.1 安装、模型种类介绍与安装&#xff0c;相信看过教程的朋友们&#xff0c;手上已经有可以操作实践的Stable Diff…

如何把非1024的采样数放入aac编码器

一. aac对数据规格要求 二、代码实现 1.初始化 2.填入数据 3.取数据 三.图解 一. aac对放入的采样数要求 我们知道aac每次接受的字节数是固定的&#xff0c;在之前的文章里有介绍libfdk_aac音频采样数和编码字节数注意 它支持的采样数和编码字节数分别是&#xff1a; fdk_aac …

马斯克收购AI.com域名巩固xAI公司地位;如何评估大型语言模型的性能

&#x1f989; AI新闻 &#x1f680; AI拍照小程序妙鸭相机上线商业工作站并邀请摄影师进行内测 摘要&#xff1a;AI拍照小程序妙鸭相机将上线面向商业端的工作站&#xff0c;并邀请摄影师进行模板设计的内测。妙鸭相机希望为行业提供更多生态产品&#xff0c;扩大行业规模&a…

JavaScript的对象+内置对象(Math+Date日期+数组+字符串)

一.创建对象 对象是由属性和方法组成的 创建对象的三种方法: 1.利用字面量创建对象 var obj{uname : 张三疯 ,age : 18 ,sex : 男 ,sayHi : function(){console.log(hi~);}} 里面的属性或者方法采用键值对的形式多个属性或者方法用逗号隔开方法冒号后面跟的是一个匿名…