🧠 Π§Π°ΡΡ‚ΡŒ 42: ΠšΠ²Π°Π½Ρ‚ΠΎΠ²Π°Ρ нСйронная ΡΠ΅Ρ‚ΡŒ Π½Π° ATmega328P

ΠœΡ‹ объСдиним ΠΊΠ²Π°Π½Ρ‚ΠΎΠ²Ρ‹Π΅ вычислСния ΠΈ Π½Π΅ΠΉΡ€ΠΎΠ½Π½Ρ‹Π΅ сСти Π² ΠΎΠ΄Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ! Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΊΠ²Π°Π½Ρ‚ΠΎΠ²Ρ‹Π΅ Π²Π΅Π½Ρ‚ΠΈΠ»ΠΈ Π΄Π»Ρ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΊΠ»Π°ΡΡΠΈΡ‡Π΅ΡΠΊΡƒΡŽ Π½Π΅ΠΉΡ€ΠΎΡΠ΅Ρ‚ΡŒ Π΄Π»Ρ обучСния.

Гибридная ΠΊΠ²Π°Π½Ρ‚ΠΎΠ²ΠΎ-классичСская ΡΠ΅Ρ‚ΡŒ:

cpp

#include <avr/random.h>
#include <avr/pgmspace.h>

#define QUBITS 4
#define INPUT_SIZE 16  // 2^QUBITS
#define HIDDEN_SIZE 8
#define OUTPUT_SIZE 4

// ΠšΠ²Π°Π½Ρ‚ΠΎΠ²ΠΎΠ΅ состояниС (4 ΠΊΡƒΠ±ΠΈΡ‚Π° = 16 Π°ΠΌΠΏΠ»ΠΈΡ‚ΡƒΠ΄)
struct QuantumState {
    int8_t real[INPUT_SIZE];
    int8_t imag[INPUT_SIZE];
};

// ΠšΠ»Π°ΡΡΠΈΡ‡Π΅ΡΠΊΠ°Ρ Π½Π΅ΠΉΡ€ΠΎΡΠ΅Ρ‚ΡŒ
struct NeuralNetwork {
    int8_t weights_ih[INPUT_SIZE * HIDDEN_SIZE];
    int8_t weights_ho[HIDDEN_SIZE * OUTPUT_SIZE];
    int8_t bias_h[HIDDEN_SIZE];
    int8_t bias_o[OUTPUT_SIZE];
};

QuantumState qstate;
NeuralNetwork net;

// ΠšΠ²Π°Π½Ρ‚ΠΎΠ²Ρ‹ΠΉ Π²Π΅Π½Ρ‚ΠΈΠ»ΡŒ Адамара (ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½Π°Ρ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°)
void quantumHadamard(uint8_t qubit) {
    uint8_t mask = 1 << qubit;
    for (uint16_t i = 0; i < INPUT_SIZE; i++) {
        if ((i & mask) == 0) {
            uint16_t j = i | mask;
            // H: (|0> + |1>) / sqrt(2)
            int8_t a_real = qstate.real[i];
            int8_t a_imag = qstate.imag[i];
            int8_t b_real = qstate.real[j];
            int8_t b_imag = qstate.imag[j];
            
            qstate.real[i] = (a_real + b_real) >> 1;
            qstate.imag[i] = (a_imag + b_imag) >> 1;
            qstate.real[j] = (a_real - b_real) >> 1;
            qstate.imag[j] = (a_imag - b_imag) >> 1;
        }
    }
}

// ΠšΠ²Π°Π½Ρ‚ΠΎΠ²Ρ‹ΠΉ Π²Π΅Π½Ρ‚ΠΈΠ»ΡŒ CNOT (Π·Π°ΠΏΡƒΡ‚Ρ‹Π²Π°Π½ΠΈΠ΅)
void quantumCNOT(uint8_t control, uint8_t target) {
    uint8_t c_mask = 1 << control;
    uint8_t t_mask = 1 << target;
    
    for (uint16_t i = 0; i < INPUT_SIZE; i++) {
        if (i & c_mask) {
            uint16_t j = i ^ t_mask;
            // МСняСм мСстами Π°ΠΌΠΏΠ»ΠΈΡ‚ΡƒΠ΄Ρ‹
            int8_t temp_real = qstate.real[i];
            int8_t temp_imag = qstate.imag[i];
            qstate.real[i] = qstate.real[j];
            qstate.imag[i] = qstate.imag[j];
            qstate.real[j] = temp_real;
            qstate.imag[j] = temp_imag;
        }
    }
}

// Π˜Π·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ ΠΊΠ²Π°Π½Ρ‚ΠΎΠ²ΠΎΠ³ΠΎ состояния (ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ вСроятностСй)
void quantumMeasure(uint8_t* probabilities) {
    for (uint16_t i = 0; i < INPUT_SIZE; i++) {
        int16_t prob = qstate.real[i] * qstate.real[i] + qstate.imag[i] * qstate.imag[i];
        probabilities[i] = prob >> 7;  // Нормализация
    }
}

// ΠšΠ²Π°Π½Ρ‚ΠΎΠ²ΠΎΠ΅ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ…
void quantumEncode(uint8_t* data) {
    // Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ |0...0>
    memset(&qstate, 0, sizeof(qstate));
    qstate.real[0] = 127;
    
    // ΠšΠΎΠ΄ΠΈΡ€ΡƒΠ΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ Π² ΠΊΠ²Π°Π½Ρ‚ΠΎΠ²Ρ‹Π΅ состояния
    for (uint8_t i = 0; i < QUBITS; i++) {
        if (data[i]) {
            quantumHadamard(i);
        }
    }
}

// ΠšΠ»Π°ΡΡΠΈΡ‡Π΅ΡΠΊΠΈΠΉ прямой ΠΏΡ€ΠΎΡ…ΠΎΠ΄ (послС ΠΊΠ²Π°Π½Ρ‚ΠΎΠ²ΠΎΠ³ΠΎ измСрСния)
void classicalForward(uint8_t* input, uint8_t* output) {
    // Π‘ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΉ слой
    int16_t hidden[HIDDEN_SIZE];
    for (uint8_t i = 0; i < HIDDEN_SIZE; i++) {
        int32_t sum = 0;
        for (uint8_t j = 0; j < INPUT_SIZE; j++) {
            sum += (int16_t)input[j] * net.weights_ih[i * INPUT_SIZE + j];
        }
        hidden[i] = (sum >> 7) + net.bias_h[i];
        if (hidden[i] < 0) hidden[i] = 0;  // ReLU
    }
    
    // Π’Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ слой
    for (uint8_t i = 0; i < OUTPUT_SIZE; i++) {
        int32_t sum = 0;
        for (uint8_t j = 0; j < HIDDEN_SIZE; j++) {
            sum += hidden[j] * net.weights_ho[i * HIDDEN_SIZE + j];
        }
        output[i] = (sum >> 7) + net.bias_o[i];
        if (output[i] < 0) output[i] = 0;
    }
}

// ΠžΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ (ΠΊΠ²Π°Π½Ρ‚ΠΎΠ²ΠΎ-классичСский Π³Ρ€Π°Π΄ΠΈΠ΅Π½Ρ‚Π½Ρ‹ΠΉ спуск)
void trainQuantumNN(uint8_t* input_data, uint8_t* target, uint8_t epochs) {
    for (uint8_t epoch = 0; epoch < epochs; epoch++) {
        // ΠšΠ²Π°Π½Ρ‚ΠΎΠ²ΠΎΠ΅ ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅
        quantumEncode(input_data);
        
        // ΠŸΡ€ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌ ΠΊΠ²Π°Π½Ρ‚ΠΎΠ²Ρ‹Π΅ Π²Π΅Π½Ρ‚ΠΈΠ»ΠΈ (Π²Π°Ρ€ΠΈΠ°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅)
        for (uint8_t i = 0; i < QUBITS; i++) {
            quantumHadamard(i);
        }
        for (uint8_t i = 0; i < QUBITS - 1; i++) {
            quantumCNOT(i, i + 1);
        }
        
        // Π˜Π·ΠΌΠ΅Ρ€ΡΠ΅ΠΌ
        uint8_t probabilities[INPUT_SIZE];
        quantumMeasure(probabilities);
        
        // ΠšΠ»Π°ΡΡΠΈΡ‡Π΅ΡΠΊΠΈΠΉ ΠΏΡ€ΠΎΡ…ΠΎΠ΄
        uint8_t output[OUTPUT_SIZE];
        classicalForward(probabilities, output);
        
        // ВычисляСм ΠΎΡˆΠΈΠ±ΠΊΡƒ
        int8_t error[OUTPUT_SIZE];
        for (uint8_t i = 0; i < OUTPUT_SIZE; i++) {
            error[i] = target[i] - output[i];
        }
        
        // ОбновляСм вСса (Π³Ρ€Π°Π΄ΠΈΠ΅Π½Ρ‚Π½Ρ‹ΠΉ спуск)
        for (uint8_t i = 0; i < HIDDEN_SIZE; i++) {
            for (uint8_t j = 0; j < INPUT_SIZE; j++) {
                net.weights_ih[i * INPUT_SIZE + j] += error[0] >> 3;
            }
        }
    }
}

// РаспознаваниС рукописных Ρ†ΠΈΡ„Ρ€ (ΠΊΠ²Π°Π½Ρ‚ΠΎΠ²ΠΎ-усилСнноС)
void setup() {
    Serial.begin(115200);
    randomSeed(analogRead(A0));
    
    // ΠžΠ±ΡƒΡ‡Π°Π΅ΠΌ Π½Π° 4 Π±ΠΈΡ‚Π°Ρ… (Ρ†ΠΈΡ„Ρ€Ρ‹ 0-15)
    for (uint8_t digit = 0; digit < 16; digit++) {
        uint8_t input[4] = {
            (digit >> 0) & 1,
            (digit >> 1) & 1,
            (digit >> 2) & 1,
            (digit >> 3) & 1
        };
        uint8_t target[4] = {
            (digit >> 0) & 1,
            (digit >> 1) & 1,
            (digit >> 2) & 1,
            (digit >> 3) & 1
        };
        trainQuantumNN(input, target, 10);
    }
    
    // ВСст
    uint8_t test_input[4] = {1, 0, 1, 0};  // Π¦ΠΈΡ„Ρ€Π° 10
    uint8_t output[4];
    
    quantumEncode(test_input);
    uint8_t probabilities[INPUT_SIZE];
    quantumMeasure(probabilities);
    classicalForward(probabilities, output);
    
    Serial.print("ΠšΠ²Π°Π½Ρ‚ΠΎΠ²ΠΎΠ΅ распознаваниС: ");
    for (uint8_t i = 0; i < 4; i++) {
        Serial.print(output[i]);
    }
    Serial.println();
}

void loop() {}

Π’Π°ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½Ρ€Π°Π²ΠΈΡ‚ΡŒΡΡ

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΉ

Π’Π°Ρˆ адрСс email Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½. ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ поля ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ *