ΠΡ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΠΈΠΌ ΠΊΠ²Π°Π½ΡΠΎΠ²ΡΠ΅ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡ ΠΈ Π½Π΅ΠΉΡΠΎΠ½Π½ΡΠ΅ ΡΠ΅ΡΠΈ Π² ΠΎΠ΄Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ! ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΠΊΠ²Π°Π½ΡΠΎΠ²ΡΠ΅ Π²Π΅Π½ΡΠΈΠ»ΠΈ Π΄Π»Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π΄Π°Π½Π½ΡΡ ΠΈ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΡΡ Π½Π΅ΠΉΡΠΎΡΠ΅ΡΡ Π΄Π»Ρ ΠΎΠ±ΡΡΠ΅Π½ΠΈΡ.
ΠΠΈΠ±ΡΠΈΠ΄Π½Π°Ρ ΠΊΠ²Π°Π½ΡΠΎΠ²ΠΎ-ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΡΠ΅ΡΡ:
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() {}