適当にやってみたのですが、うまく学習できません・・・
ちゃんと調べてやるべきか。
画面にマウスなんかで数字を書いて、下の数字ボタンで学習します。上の判定ボタンを押すと、標準出力に判定結果を表示します。
3文字くらいまでなら認識できるようになるんだけど。
import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import javax.swing.*; public class Perceptron extends JComponent implements ActionListener, MouseMotionListener{ Image img = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB); Graphics bg = img.getGraphics(); Point pt; final int mesh = 10; double[][][] perc = new double[10][mesh][mesh]; double[] b = new double[10]; double k = 0.1;//学習係数 public static void main(String[] args){ JFrame f = new JFrame("パーセプトロン"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setSize(320, 400); //描画領域 Perceptron pc = new Perceptron(); pc.addMouseMotionListener(pc); pc.clear(); f.add(pc); //数字ボタン JPanel p = new JPanel(); p.setLayout(new GridLayout(2, 5)); for(int i = 0; i < 10; ++i){ JButton b = new JButton(i +""); p.add(b); b.addActionListener(pc); } f.add(p, BorderLayout.SOUTH); //判定ボタン JButton b = new JButton("判定"); b.addActionListener(pc); f.add(b, BorderLayout.NORTH); //ウィンドウ表示 f.setVisible(true); } /** ボタンが押されたときの処理 */ public void actionPerformed(ActionEvent e) { //手書き結果を学習メッシュに合わせる BufferedImage bi = new BufferedImage(mesh, mesh, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = (Graphics2D) bi.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g2.drawImage(img, 0, 0, mesh, mesh, this); if("判定".equals(e.getActionCommand())){ //判定ボタンの処理 double mr = 0; int ans = 0; for(int i = 0; i < 10; ++i){ double r = 0; for(int x = 0; x < mesh; ++x){ for(int y = 0; y < mesh; ++y){ double d = (255 - bi.getRGB(x, y) & 255) / 255.; r += d * perc[i][x][y]; } } r += b[i]; System.out.printf("%d:%.2f ", i, r); if(mr < r){ mr = r; ans = i; } } System.out.println("\n答えは" + ans); clear(); return; } //数字ボタンが押されたときの学習処理 int idx = Integer.parseInt(e.getActionCommand()); for(int i = 0; i < 10; ++i){ double yi = (i == idx) ? 1 : -1; double in = 0; for(int x = 0; x < mesh; ++x){ for(int y = 0; y < mesh; ++y){ double d = (255 - bi.getRGB(x, y) & 255) / 255.; in += d * perc[i][x][y]; } } in = (in + b[i]) * yi; System.out.printf("%d:% .2f ", i, in); if(in <= 0){ //再学習 for(int x = 0; x < mesh; ++x){ for(int y = 0; y < mesh; ++y){ double d = (255 - bi.getRGB(x, y) & 255) / 255.; perc[i][x][y] += d * k * yi; b[i] += k * yi; } } } } System.out.println(); clear(); } /** マウスで描画 */ public void mouseDragged(MouseEvent e) { Point old = pt; pt = e.getPoint(); if(old != null){ bg.setColor(Color.BLACK); ((Graphics2D)bg).setStroke(new BasicStroke(25)); bg.drawLine(old.x, old.y, pt.x, pt.y); repaint(); } } public void mouseMoved(MouseEvent e) { pt = null; } //描画 @Override protected void paintComponent(Graphics g) { g.drawImage(img, 0, 0, this); } private void clear(){ bg.setColor(Color.WHITE); bg.fillRect(0, 0, 300, 300); repaint(); } }