【リアイム】


タップ(クリック)で消す



よみこみ中…








閉じる
もくじ

リアイム

アウトプット&知識の共有

【人工知能】 ニューラルネットワークの接続を作ろう! 綺麗な接続をめざす

完成イメージ
f:id:a1t2s2u2:20220306154958p:plain

人工知能研究のために作ったプログラムですが、めちゃ綺麗だったので記事として保存しとく!
自由に設定して、簡単に作れるぜ
注意点として…
ニューロン数は1万以上にすると重くなる
接続限界キョリはニューロンの接続の可能性を変更できるよ…
平面の大きさ自体は1000×1000だから、キョリは最低でも50から設定しよう
ニューロンが多すぎたり、キョリを大きくしすぎると、全部に接続して重くなるかも…
おすすめはニューロン数1000, キョリ100だよ
GENERATE(作成)したら、CREATURES(生物)に追加されるので、クリック(タップ)してね
例としてID:0のネットワークが追加されているよ!

※ 全然わかりやすくない説明です。

簡単に
おすすめは

作成したら、下の表に追加されるので、クリック(タップ)して表示させましょう。

ニューロン数を1万とか大きくしてしまうと重くなるかも
キョリも1000とかにすると接続しすぎるかも

他にもたくさん変数はありますが、設定は面倒なので今回は2つだけ






GENERATE

項目数値
ニューロン
接続限界キョリ
GENERATE



CREATURES

ID表示するQUANTITY


// Object.js

コードはこちら

<div style="color: white;min-height: 100%;background: rgb(34, 34, 34);padding: 15% 0;overflow: scroll;">
    <center style="padding: 20px;">
        <input type="range" value="350" min="200" max="1500" onchange="document.getElementById('canvas').style.width = this.value+'px';document.getElementById('canvas').style.height = this.value+'px';"><br>
        <canvas id='canvas'></canvas>
    </center>
    <style>
        #canvas {
            border: 2px solid skyblue;
            width: 350px;height: 350px;
            margin-bottom: 50px;
        }
        #percentage-title {
            font-size: 1.2rem;
        }
        #percentage-title::after {
            content: ' : ';
        }
        #percentage-number {
            font-size: 1.2rem;
        }
        #percentage-number::after {
            content: '%';
        }
    </style>

    <center>
                <h1>GENERATE</h1>
                <table>
                    <tr>
                        <th>項目</th><th>数値</th>
                    </tr>
                    <tr>
                        <td>ニューロン数</td><td><input type="number" id="ニューロン数" value="1000"></td>
                    </tr>
                    <tr>
                        <td>接続限界キョリ</td><td><input type="number" id="接続限界キョリ" value="500"></td>
                    </tr>
                </table>
                <button onclick="GenerateCreatures(document.getElementById('ニューロン数').value,document.getElementById('接続限界キョリ').value);">GENERATE</button>
                <br><br>
        <h1>CREATURES</h1>
        <table id="CREATURES-table">
            <tr><th>ID</th><th>GENERATION</th><th>QUANTITY</th></tr>
        </table>
    </center>
</div>

<style>
table {
background: rgba(0,0,0,0);
}
table tr {
    text-align: center;
    cursor: pointer;
}
table tr:hover {
    background: gray;
    
}
table th {
    color: aqua;
    background: rgba(0,0,0,0) !important;
    padding: 7px;
}
table td {
    color: white;
    border-bottom: 1px solid gray;
    padding: 7px;
}
</style>
<script>
const canvas = document.getElementById('canvas');
canvas.width = 3000;canvas.height = 3000;
const ctx = canvas.getContext('2d');
</script>

// Object.js
<script>
function error(sentence) {
    console.log('Error :', sentence);
}

function distance(p, q) {
    let d = 0;
    p.forEach((e, i) => {
        d += (e - q[i])**2
    });
    return Math.sqrt(d)
}

function round(v) {
    if(typeof v == 'object') { // 配列の場合
        for(var i=0;i<v.length;++i) {
            v[i] = round(v[i]);
        }
        return v
    } else if(typeof v == 'number') { // 数値
        return Math.round( v * 100) / 100
    } else {
        error('The value cannot be rounded off.\nvalue is '+v);
    }
}

function random(max) {
    return round(Math.random() * max)
}

function keys(dict) {
    return Array.from(Object.keys(dict))
}

function percentage(title, number) {
    console.log(title, ":", number * 100);
}

// network.js
class Neuron {
    constructor(info, id) {
        let new_position = [];
        info.shape.forEach( s => {
            new_position.push(Math.random() * s);
        });
        this.id = id;
        this.value = 0;
        this.threshold = random(limit.threshold);
        this.connections = [];
        this.position = round(new_position);
    }
}

class Network {
    // Generate network
    constructor( // ex
            info = {
                shape : [1000, 1000],
                quantity : 1000,
            },
            limit = {
                connection : 100,
                weight : 5,
                threshold : 10,
            },
            id = '0',
            generation = 1,
        ) {
        this.ID = id;
        this.DNA = [];
        this.GENERATION = generation;
        this.INFO = info;
        this.LIMIT = limit;
        this.NETWORK = {};
        // Generate neurons
        for(var _=0;_<info.quantity;++_) {
            let new_id = '0';
            while(keys(this.NETWORK).includes(new_id)) {
                new_id = String(Math.round(Math.random() * 10**5));
            }
            this.NETWORK[new_id] = new Neuron(info, new_id);

        }
        // Generate connections
        var _ = 0;
        for(var key in this.NETWORK) {
            let neuron = this.NETWORK[key];
            for(var target_key in this.NETWORK) {
                if(key != target_key) {
                    let target_neuron = this.NETWORK[target_key];
                    if(this.connect(neuron.position, target_neuron.position)) {
                        neuron.connections.push({
                            'id' : target_key,
                            'weight' : random(limit.weight),
                        });
                    }
                }
            }

            ++_;
        }
        document.getElementById('CREATURES-table').innerHTML += "<tr onclick='creatures["+this.ID+"].draw();'><td>"+this.ID+"</td><td>"+this.GENERATION+"</td><td>"+this.INFO.quantity+"</td></tr>"
    }
    input(data, type) {
        switch(type) {
            case 'eye':

                break;
        }
    }
    // Whether neurons connect true/false
    connect(p, q) {
        return Math.random() <= -distance(p, q)/(this.LIMIT.connection) + 1
    }
    // Details of network
    show(detail=false) {
        let sum_connections = 0;
        for(var key in this.NETWORK){
            let neuron = this.NETWORK[key];
            sum_connections += neuron.connections.length;
            if(detail) {
                console.log('id :', neuron.id, '\nvalue :', neuron.value, '\nconnections :', neuron.connections, '\nposition :', neuron.position);
            }
        }
        console.log('【 NETWORK SHOW 】', '\nID :', this.ID, '\nGENERATION :', this.GENERATION, '\nINFO :', this.INFO, '\nsum connections :', sum_connections, '\naverage connections :', sum_connections/keys(this.NETWORK).length);
    }
    draw() {
        // canvasサイズの変更
        let PADDING = [this.INFO.canvas.padding[0] * this.INFO.shape[0] * this.INFO.canvas.quality, this.INFO.canvas.padding[1] * this.INFO.shape[1] * this.INFO.canvas.quality,]
        canvas.width = this.INFO.shape[0] * this.INFO.canvas.quality + PADDING[0] * 2;canvas.height = this.INFO.shape[1] * this.INFO.canvas.quality + PADDING[1] * 2;
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        for(var key in this.NETWORK) {
            let neuron = this.NETWORK[key]
            // neuronsの表示
            ctx.beginPath();
            ctx.arc(neuron.position[0] * this.INFO.canvas.quality + PADDING[0], neuron.position[1] * this.INFO.canvas.quality + PADDING[1], canvas.width * this.INFO.canvas.neuron, 0*Math.PI/180, 360*Math.PI/180, false) ;
            ctx.fillStyle = "gray" ;
            ctx.fill();
            ctx.strokeStyle = "white";
            ctx.lineWidth = canvas.width * 0.001;
            ctx.stroke();
            // connectionsの表示
            ctx.strokeStyle = "aqua";
            ctx.lineWidth = canvas.width * 0.0005 ;
            neuron.connections.forEach(connection => {
                var destination = this.NETWORK[connection['id']].position;
                ctx.beginPath();
                ctx.moveTo( neuron.position[0] * this.INFO.canvas.quality + PADDING[0], neuron.position[1] * this.INFO.canvas.quality + PADDING[1]);
                ctx.lineTo( destination[0] * this.INFO.canvas.quality + PADDING[0], destination[1] * this.INFO.canvas.quality + PADDING[1]);
                ctx.stroke();
            });
        }
    }
}



// main.js
let creatures = {};
function GenerateCreatures(new_quality=1000, new_connection=100) {
    let new_id = '0';
    while(Array.from(Object.keys(creatures)).includes(new_id)) {
        new_id = String(Math.round(Math.random() * 10**5));
    }
    creatures[new_id] = new Network(
        info = {
            shape : [1000, 1000],
            quantity : new_quality,
            canvas : {
                quality : 3,
                padding : [0.1, 0.1], // 割合指定
                neuron: 0,
            }
        },
        limit = {
            connection : new_connection,
            weight : 5,
            threshold : 10,
        },
        id = new_id,
        generation = 1,
    );
    creatures[new_id].show();
}

for(var _=0;_<1;++_) {
    GenerateCreatures();
}

</script>