机器学习-16-CNN卷积神经网络01

学习来源:日撸 Java 三百行(81-90天,CNN 卷积神经网络)_闵帆的博客-CSDN博客

卷积神经网络(CNN)

卷积神经网络与普通神经网络非常相似,它们都由具有可学习的权重和偏置常量(biases)的神经元组成。每个神经元都接收一些输入,并做一些点积计算,输出是每个分类的分数,普通神经网络里的一些计算技巧到这里依旧适用。

CNN 有2大特点

1.能够有效的将大数据量的图片降维成小数据量。

2.能够有效的保留图片特征,符合图片处理的原则。

解决的问题

1.图像处理的数据量大,成本很高,效率低。

2.之前的数据化的过程中很难保留原本的特征。

CNN 由3个部分构成

1.卷积层(提取图像特征)

2.池化层(降维,防止过拟合)

3.全连接层(输出结果)

该节对数据的读取和存储

代码:

读取部分

package 日撸Java300行_81_90;

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;

/**
 * Manage the dataset.
 * 
 * @author Hui Xiao
 */
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>();
	}// Of the first constructor

	/**
	 *********************** 
	 * 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);
	}// Of append

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

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

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

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

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

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

	/**
	 *********************** 
	 * 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;
		}//Of the first constructor

		/**
		 *********************** 
		 * 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;
				} // Of if

				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);
				} // Of if
			} // Of if
		}// Of the second constructor

		/**
		 *********************** 
		 * Getter.
		 *********************** 
		 */
		public double[] getAttributes() {
			return attributes;
		}// Of getAttributes

		/**
		 *********************** 
		 * Getter.
		 *********************** 
		 */
		public Double getLabel() {
			if (labelIndex == -1)
				return null;
			return label;
		}// Of getLabel

		/**
		 *********************** 
		 * toString.
		 *********************** 
		 */
		public String toString(){
			return Arrays.toString(attributes) + ", " + label;
		}//Of toString
	}// Of class Instance
}// Of class Dataset

管理卷积核尺寸的类

package 日撸Java300行_81_90;

/**
 * The size of a convolution core.
 * 
 * @author Hui Xiao
 */
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;
	}// Of the first constructor

	/**
	 *********************** 
	 * 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);
	}// Of divide

	/**
	 *********************** 
	 * 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);
	}// Of subtract

	/**
	 *********************** 
	 * @param The
	 *            string showing itself.
	 *********************** 
	 */
	public String toString() {
		String resultString = "(" + width + ", " + height + ")";
		return resultString;
	}// Of toString

	/**
	 *********************** 
	 * Unit test.
	 *********************** 
	 */
	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);
		} // Of try

		System.out.println(
				"" + tempSize1 + " - " + tempSize2 + " + 1 = " + tempSize1.subtract(tempSize2, 1));
	}// Of main
}// Of class Size

以前对于数据使用整数型常量和字符型常量, 其实还可以有枚举类型。

package 日撸Java300行_81_90;

/**
 * Enumerate all layer types.
 * 
 * @author Hui Xiao
 */
public enum LayerTypeEnum {
	INPUT, CONVOLUTION, SAMPLING, OUTPUT;
}//Of enum LayerTypeEnum

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值