Главная страница
Навигация по странице:

  • Исходный код программы public class Main

  • public GUI()

  • Нейронные сети. Лабораторная работа № 2.. Лабораторная работа 2 магистрант гр. 3Мпп1801 Симанова Д. А. подпись дата Проверил


    Скачать 77.45 Kb.
    НазваниеЛабораторная работа 2 магистрант гр. 3Мпп1801 Симанова Д. А. подпись дата Проверил
    АнкорНейронные сети
    Дата21.12.2019
    Размер77.45 Kb.
    Формат файлаdocx
    Имя файлаЛабораторная работа № 2..docx
    ТипЛабораторная работа
    #101433
    страница2 из 2
    1   2
    Ход выполнения работы

    Структурная схема нейронной сети

    Вывод.

    Проделав работу, можно выявить достоинства и недостатки данного метода обучения однослойного персептрона.

    Преимущества SG:

    • Метод приспособлен для динамического обучения, когда обучающие объекты поступают потоком, и надо быстро обновлять вектор.

    • Алгоритм способен обучаться на избыточно больших выборках за счет того, что случайной подвыборки может хватить для обучения.

    Недостатки SG и способы их устранения:



    Исходный код программы

    public class Main
    {
    public static void main(String[] args)
    {
    GUI gui = new GUI();
    }
    }
    public class NeuralNet {
    private int inputVectorSize;
    private Neuron[] layer;
    private int epochNumber;
    private boolean complete;
    private double[] error;
    private double errorNet;
    private double eta = 0.00000001;
    private double epsThreshold = 0.000000001;

    public double getErrorNet() {
    return errorNet;
    }

    public NeuralNet(int inputVectorSize, int outputNeuronsCount) {
    this.inputVectorSize = inputVectorSize;
    layer = new Neuron[outputNeuronsCount];
    for (int j = 0; j < outputNeuronsCount; j++)
    {
    layer[j] = new Neuron(inputVectorSize);
    }
    error = new double[layer.length];
    }

    public double[] getError() {
    return error;
    }

    public int getEpochNumber() {
    return epochNumber;
    }

    public boolean isComplete() {
    return complete;
    }

    public void setComplete(boolean complete) {
    this.complete = complete;
    }

    public void train(Vector[] vectorSet) throws InterruptedException
    {
    // эпоха обучения равна нулю
    epochNumber = 0;
    double[][] deltaWeight = new double[layer.length][];
    for (int j = 0; j < layer.length; j++)
    {
    // создаем пустой массив для каждого
    //синаптического веса wij каждого j-го нейрона в слое
    deltaWeight[j] = new double[layer[j].getWeight().length];
    }
    // массив для хранения ошибки каждого нейрона
    error = new double[layer.length];
    Random random = new Random();

    while (true)
    {
    // Шаг 3 и 4. Берем случайным образом обучающий вектор
    int m = random.nextInt(vectorSet.length);
    // Шаг 5
    for (int j = 0; j < layer.length; j++) //перебор нейронов
    {
    layer[j].calcOut(vectorSet[m].getX());
    }

    errorNet = 0.0;
    // Шаг 6
    for (int j = 0; j < layer.length; j++)
    { // считаем ошибка каждого j-го нейрона
    error[j] =
    (vectorSet[m].getDesireOutputs()[j] -
    layer[j].getOut()) *
    (vectorSet[m].getDesireOutputs()[j] -
    layer[j].getOut());
    errorNet += 0.5 * error[j];
    }
    // Шаг 7
    if (errorNet < epsThreshold) // ошибка < ошибки порог.
    break; // прерываем внешний цикл
    // критерий останова обучения

    // Шаг 8. Цикл коррекции синаптических весов
    for (int j = 0; j < layer.length; j++)
    {
    layer[j].calcSigma(vectorSet[m].getDesireOutputs()[j]);
    int n = layer[j].getWeight().length; // кол-во синаптических весов j-го нейрона
    for (int i = 0; i < n; i++)
    {
    deltaWeight[j][i] = - eta * layer[j].getSigma() *
    vectorSet[m].getX()[i];
    }
    layer[j].correctWeights(deltaWeight[j]);
    }
    epochNumber++;
    }


    complete = true;
    }

    public double[] test(double[] vector)
    {
    double[] outVector = new double[layer.length];
    for (int j = 0; j < layer.length; j++)
    {
    layer[j].calcOut(vector);
    outVector[j] = Math.round(layer[j].getOut() * 100.0) / 100.0;
    }
    return outVector;
    }
    }

    import java.util.Random;

    public class Neuron {
    private double[] weight;
    private double out; // y
    private double sum; // net
    private double sigma;
    public static Random random = new Random();
    public double rangeMin = -0.0003;
    public double rangeMax = 0.0003;

    public double getSigma() {
    return sigma;
    }

    public void calcSigma(double desireResponse)
    {
    this.sigma = -(desireResponse - this.out) * derivativeActivationFunc(sum);
    }

    public void calcOut(double[] x)
    {
    this.sum = 0;
    for (int i = 0; i < x.length; i++)
    {
    sum += x[i]*weight[i];
    }
    this.out = activationFunc(sum);
    }

    public Neuron(int weightsCount) {
    this.weight = new double[weightsCount];
    this.out = 0.0;
    randomizeWeights();
    }

    public void randomizeWeights()
    {
    for (int i = 0; i < weight.length; i++)
    {
    weight[i] = rangeMin + (rangeMax - rangeMin) * random.nextDouble();
    }
    }

    private double activationFunc(double val)
    {
    return 1.0 / (1.0 + Math.exp(-val));
    }

    private double derivativeActivationFunc(double val)
    {
    return activationFunc(val) * (1.0 - activationFunc(val));
    }

    public double getOut()
    {
    return out;
    }

    public void correctWeights(double[] deltaWeight)
    {
    for (int i = 0; i < weight.length; i++)
    {
    weight[i] += deltaWeight[i];
    }
    }

    public double[] getWeight()
    {
    return weight;
    }
    }
    public class Vector
    {
    private double[] x;
    private double[] desireOutputs;

    public Vector(double[] x, double[] desireOutputs) {
    this.x = new double[x.length +1];
    this.x[0] = 1;
    for (int i = 1; i < x.length; i++)
    {
    this.x[i] = x[i - 1];
    }
    this.desireOutputs = desireOutputs;
    }

    public double[] getX() {
    return x;
    }

    public double[] getDesireOutputs() {
    return desireOutputs;
    }
    }

    import javax.imageio.ImageIO;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.IntStream;

    import static javax.swing.JOptionPane.showMessageDialog;

    public class GUI extends JFrame
    {
    private JPanel rootPanel;
    private JButton buttonTrain;
    private JPanel imagePanel;
    private JLabel imageLabel;
    private JLabel labelError;
    private JLabel labelAnswer;
    private JLabel labelEpoch;
    private JTextArea textAreaAnswer;
    private JButton buttonTest;
    private JLabel labelNetError;
    private NeuralNet neuralNet;

    public GUI()
    {
    setContentPane(rootPanel);
    pack();
    setTitle("Обучение методом SGD");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setVisible(true);
    buttonTest.setEnabled(false);

    buttonTrain.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    train();
    }
    });
    buttonTest.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
    test();
    }
    });
    }

    public void train()
    {
    try
    {
    buttonTest.setEnabled(false);
    Vector[] trainVectorSet = readTrainVectors("C://Train");
    neuralNet = new NeuralNet(trainVectorSet[0].getX().length, trainVectorSet[0].getDesireOutputs().length);
    neuralNet.setComplete(false);

    Runnable task1 = () -> { try { neuralNet.train(trainVectorSet); } catch (InterruptedException e) {} };
    Thread thread1 = new Thread(task1);
    Runnable task2 = () -> {
    while (!neuralNet.isComplete())
    {
    labelEpoch.setText("Номер эпохи: " + neuralNet.getEpochNumber());
    double[] err = neuralNet.getError();
    StringBuilder s = new StringBuilder();
    IntStream.range(0, err.length)
    .forEach(i -> s.append(String.format("[%.5f] ", err[i])));

    labelError.setText("Ошибка нейронов: " + s);
    labelNetError.setText("Ошибка вектора: " + neuralNet.getErrorNet());
    }
    textAreaAnswer.append("Обучение завершено\n");
    buttonTest.setEnabled(true);
    };
    Thread thread2 = new Thread(task2);

    thread1.start();
    thread2.start();
    }
    catch (IOException e)
    {
    showMessageDialog(null, "Файл не найден");
    }
    catch (Exception e)
    {
    showMessageDialog(null, e.toString());
    }

    int f = 0;
    }

    public void test() {
    try
    {
    String path = "c://Test//";
    int totalCount = 0;
    int totalPassed = 0;
    for (int i = 0; i < 3; i++)
    {
    File[] files = new File(path + i).listFiles();
    int count = 0;
    int passed = 0;
    for (File file : files)
    {
    double[] testVector = readVector(file.getPath());
    double[] answer = neuralNet.test(testVector);
    count++;
    if (i == getMaxNeuronIdx(answer)) {
    passed++;
    }
    }
    double percent = (double)passed / count * 100.0;
    textAreaAnswer.append(String
    .format("Процент распознавания класса образов №%d: %.2f%n", i, percent));
    totalCount += count;
    totalPassed += passed;
    }
    double percent = 100.0 - (double)totalPassed / totalCount * 100.0;
    textAreaAnswer.append(String
    .format("Процент ошибки распознавания: %.2f%n", percent));
    }
    catch (IOException e)
    {
    showMessageDialog(null, "Файл не найден");
    }
    catch (Exception e)
    {
    showMessageDialog(null, e.toString());
    }
    }

    public int getMaxNeuronIdx(double[] answer)
    {
    int maxIdx = 0;
    for (int i = 1; i < answer.length; i++)
    {
    if (answer[maxIdx] < answer[i])
    maxIdx = i;
    }
    return maxIdx;
    }

    public double[] readVector(String path) throws IOException
    {
    BufferedImage image = ImageIO.read(new File(path));
    int[][] grayImage = imageToGrayScale(image);
    double[] imageVector = imageToVector(grayImage);
    return imageVector;
    }


    public Vector[] readTrainVectors(String rootDir) throws IOException
    {
    List trainVectorSet = new ArrayList();

    for (int i = 0; i < 3; i++)
    {
    File[] files = new File(rootDir + "//" + i).listFiles();
    for (File file : files)
    {
    BufferedImage image = ImageIO.read(file);

    int[][] grayImage = imageToGrayScale(image);
    double[] imageVector = imageToVector(grayImage);

    double[] desireOutputs = new double[3];
    for (int k = 0; k < desireOutputs.length; k++)
    {
    desireOutputs[k] = i == k ? 1 : 0;
    }

    trainVectorSet.add(new Vector(imageVector, desireOutputs));
    //imageLabel.setIcon(new ImageIcon(image));
    }
    }
    return (Vector[])trainVectorSet.toArray(new Vector[trainVectorSet.size()]);
    }

    public int[][] imageToGrayScale(BufferedImage image)
    {
    int[][] resultImage = new int[image.getWidth()][image.getHeight()];
    for(int x = 0; x < image.getWidth(); x++)
    {
    for (int y = 0; y < image.getHeight(); y++)
    {
    Color c = new Color(image.getRGB(x, y));
    resultImage[x][y] = (c.getRed() + c.getGreen() + c.getBlue()) / 3;
    }
    }
    return resultImage;
    }

    public BufferedImage grayScaleToImage(int[][] grayImage)
    {
    int height = grayImage[0].length;
    int width = grayImage[1].length;
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    for (int x = 0; x < width; x++)
    {
    for (int y = 0; y < height; y++)
    {
    Color c = new Color(grayImage[x][y], grayImage[x][y], grayImage[x][y], 0);
    image.setRGB(x, y, c.getRGB());
    }
    }
    return image;
    }


    public double[] imageToVector(int[][] image)
    {
    double[] resultVector = new double[image[0].length * image[1].length];
    int i = 0;
    for(int x = 0; x < image.length; x++)
    {
    for (int y = 0; y < image.length; y++)
    {
    resultVector[i++] = image[x][y];
    }
    }
    return resultVector;
    }

    }


    1   2


    написать администратору сайта