

Вход
Регистрация | Забыли пароль?
Поиск
Рубрики
Рейтинг
Облако тэгов
windows, raspberry pi 3, raspbian, умный дом, gpio, ubuntu, osmc, windows 10, linux, игры, python, установка ос, raspberry pi 2, raspberry pi zero, raspberry pi zero w, слежение, самолёт, http, diy, 1c-битрикс, нейросеть, сеть, кластер, бесперебойник, акустикаБоковое меню
Небольшая нейронная сеть на Raspberry Pi Pico
В этом посте я вам покажу как создать достаточно эффективную нейронную сеть на Raspberry Pi Pico!

Для начала каким-либо образом копируем этот код в память pico:
from random import random
from math import exp
class NeyroNet:
def __init__(self, n_inputs, hiddens_layer, n_outputs):
self.network = list()
self.n_outputs = n_outputs
hidden_layer = [{`weights`:[random() for i in range(n_inputs + 1)]} for i in range(hiddens_layer[0])]
self.network.append(hidden_layer)
for layer in hiddens_layer[1:]:
hidden_layer = [{`weights`:[random() for i in range(len(self.network[-1])+1)]} for i in range(layer)]
self.network.append(hidden_layer)
output_layer = [{`weights`:[random() for i in range(hiddens_layer[-1] + 1)]} for i in range(n_outputs)]
self.network.append(output_layer)
def activate(self, weights, inputs):
activation = weights[-1]
for i in range(len(weights)-1):
activation += weights[i] * inputs[i]
return activation
def transfer(self, activation):
return 1.0 / (1.0 + exp(-activation))
def forward_propagate(self, row):
inputs = row
for layer in self.network:
new_inputs = []
for neuron in layer:
activation = self.activate(neuron[`weights`], inputs)
neuron[`output`] = self.transfer(activation)
new_inputs.append(neuron[`output`])
inputs = new_inputs
return inputs
def transfer_derivative(self, output):
return output * (1.0 - output)
def backward_propagate_error(self, expected):
for i in reversed(range(len(self.network))):
layer = self.network[i]
errors = list()
if i != len(self.network)-1:
for j in range(len(layer)):
error = 0.0
for neuron in self.network[i + 1]:
error += (neuron[`weights`][j] * neuron[`delta`])
errors.append(error)
else:
for j in range(len(layer)):
neuron = layer[j]
errors.append(expected[j] - neuron[`output`])
for j in range(len(layer)):
neuron = layer[j]
neuron[`delta`] = errors[j] * self.transfer_derivative(neuron[`output`])
def update_weights(self, row, l_rate):
for i in range(len(self.network)):
inputs = row[:-1]
if i != 0:
inputs = [neuron[`output`] for neuron in self.network[i - 1]]
for neuron in self.network[i]:
for j in range(len(inputs)):
neuron[`weights`][j] += l_rate * neuron[`delta`] * inputs[j]
neuron[`weights`][-1] += l_rate * neuron[`delta`]
def train_network(self, train, l_rate, n_epoch, err_val_threshold=0):
for epoch in range(n_epoch):
sum_error = 0
for row in train:
outputs = self.forward_propagate(row)
expected = [0 for i in range(self.n_outputs)]
expected[row[-1]] = 1
sum_error += sum([(expected[i]-outputs[i])**2 for i in range(len(expected))])
self.backward_propagate_error(expected)
self.update_weights(row, l_rate)
pdat = `>epoch=%d, lrate=%.1f, error=%.10f` % (epoch, l_rate, sum_error)
print(pdat, end=`\r`)
if(sum_error < err_val_threshold):
print(` ` * len(pdat), end=`\r`)
print(`THRESHOLD WITH EPOCH > ` + str(epoch))
break
def predict(self, row):
outputs = self.forward_propagate(row)
return outputs.index(max(outputs))
def save(self, filename):
with open(filename, `w`) as sv:
sv.write(str(self.network))
sv.close()
def load(self, filename):
with open(filename, `r`) as sv:
data = sv.read()
sv.close()
self.network = eval(data)
Называем файл как угодно
Далее заходим в консоль pico через minicom или через thonny
Прописываем для инициализации нейронной сети
import <скопированный файл без приставки .py>
net = NeyroNet(3, [6], 2) # 3 - Сколько входов, [6] - Это список слоёв
net = NeyroNet(3, [6], 2) # 3 - Сколько входов, [6] - Это список слоёв
Далее берём любой dataset
dataset = [[1, 0 ,0 ,1], [1, 1, 0, 1], [0, 1, 1, 0], [0, 0, 1, 0]]
Вы спросите: "Почему у тебя в каждом элементе по 4 значения а входов всего 4?"
Дело в том что самое последнее значение в элементе это и есть выходные данные, а все остальные - это входные!
После этого обучаем нейросеть
net.train_network(dataset, l_rate=0.5, n_epoch=10000, err_val_threshold=0.0009)
P.S. параметр err_val_threshold нужен для того чтобы не ждать пока нейросеть пройдёт все эпохи, этот параметр указывает пороговое значение ошибки т.e. если ошибка будет меньше этого значения обучение прекратится!
Ну вот мы и обучили нейросеть! Теперь давайте проверим что она выдаёт!
Как мы помним у нас всего выходных класса
net.predict([1, 0, 1]) # возвращает 1 т.е какой выход (начинается с 0)
net.forward_propagate([0, 0, 0]) # возвращает [0.99998464, 0.00006544]
net.forward_propagate([0, 0, 0]) # возвращает [0.99998464, 0.00006544]
И чтобы сохранить текущие веса нужно прописать:
net.save(`<имя файла>`)
А чтобы загрузить веса сети нужно воопервых при создании объекта сети нужно указать столько же выходов, сколько и было сохранено, а иначе будет ошибка!
net.load(`<имя файла>`)
Вот и всё!
Надеюсь вам понравилась статья!
Источник