Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Prediksi Hujan DIY Menggunakan Arduino, Python dan Keras

Komponen dan persediaan

Kotak plastik kecil dengan tutup yang dapat dilepas (milik saya memiliki sekrup)
× 1
tiga dudukan baterai AAA
× 1
tiga baterai isi ulang AAA
× 1
Panel surya kecil 6V
× 1
SparkFun Arduino Pro Mini 328 - 5V/16MHz
× 1
dioda 1N4004
× 1
NPN Transistor Serbaguna
× 1
sensor hujan
× 1
Modul komunikasi serial HC-12
× 1
Modul serial USB HC-12
× 1
SparkFun Atmospheric Sensor Breakout - BME280
× 1
BH1750
× 1
PCB, kabel, solder, konektor sekrup konektor KF301-2P , konektor pcb pria &wanita, lem
× 1
Regulator 3.3V
× 1

Alat dan mesin yang diperlukan

USB ke adaptor FTDI serial FT232RL
Bor
Besi solder (generik)
Obeng

Tentang proyek ini

Pertama, beberapa patah kata tentang proyek ini, motivasi, teknologi yang terlibat, dan produk akhir yang akan kami buat.

Jadi tujuan besarnya di sini jelas untuk memprediksi hujan di masa depan (kami akan mencoba 6 jam). Prediksinya akan menjadi ya atau tidak (boolean dalam istilah pemrograman). Saya telah mencari dari tutorial tentang hal ini dan saya belum menemukan satu yang lengkap dalam segala hal. Jadi saya akan membawa ini ke pendekatan yang sama sekali baru dan masuk ke setiap aspeknya. Untuk itu kita akan:

  • bangun stasiun cuaca diri kita sendiri. Stasiun harus benar-benar mati jaringan dengan panel surya, dan mode daya yang sangat rendah (beberapa lusin microamps hour)
  • program stasiun sehingga mengumpulkan data dan mengirimkannya setiap sepuluh menit ke stasiun pangkalan
  • mengumpulkan data di base station dan menyimpannya (dalam database)
  • menggunakan jaringan saraf (Perpustakaan Keras) dan pustaka Python lainnya seperti pandas filter, bersihkan dan praproses data, lalu masukkan ke jaringan saraf untuk melatih "model" untuk memprediksi hujan turun atau tidak
  • akhirnya prediksi apakah akan hujan atau tidak dalam 6 jam ke depan dan beri tahu pengguna melalui email

Saya pribadi menggunakan stasiun cuaca ini untuk mengumpulkan data (Anda dapat mengunduh data di langkah selanjutnya jika Anda mau). Dengan hanya sekitar 600 hari data cuaca, sistem dapat membuat prediksi apakah akan hujan atau tidak dalam 6 jam ke depan dengan akurasi sekitar 80% tergantung pada parameter yang tidak terlalu buruk.

Tutorial ini kami akan membawa Anda melalui semua langkah yang diperlukan untuk memprediksi curah hujan dari awal. Kami akan membuat produk akhir yang melakukan pekerjaan praktis, tanpa menggunakan cuaca eksternal atau API pembelajaran mesin. Kita akan belajar di sepanjang jalan bagaimana membangun stasiun cuaca praktis (daya rendah dan di luar jaringan) yang benar-benar mengumpulkan data dalam jangka waktu yang lama tanpa pemeliharaan. Setelah itu Anda akan mempelajari cara memprogramnya menggunakan Arduino IDE. Bagaimana mengumpulkan data ke dalam database di base station (server). Dan bagaimana mengolah data (Panda) dan menerapkan jaringan saraf (Keras) dan kemudian memprediksi curah hujan.

Langkah 1:Bagian dan Alat untuk Membangun Stasiun

Bagian:

1. Kotak plastik kecil dengan tutup yang dapat dilepas (milik saya memiliki sekrup). Ukuran kotak harus cukup besar agar sesuai dengan komponen kecil dan baterai. Kotak saya berukuran 11 x 7 x 5 cm

2. tiga tempat baterai AAA

3. tiga baterai isi ulang AAA

4. Panel surya kecil 6V

5. Arduino Pro Mini 328p

6. dioda, 1N4004 (untuk mencegah arus balik dari baterai ke panel)

7. transistor NPN kecil dan resistor 1k (untuk menghidupkan dan mematikan komponen)

8. sensor hujan

9. Modul komunikasi serial HC-12

10. Modul serial USB HC-12 (untuk stasiun pangkalan)

11. Modul sensor bosch BME280 (untuk kelembaban, suhu, tekanan)

12. Modul penginderaan cahaya BH1750

13. PCB, kabel, solder, konektor sekrup KF301-2P plug in, konektor pcb pria &wanita, lem

14. Pengatur 3.3V

15. stasiun pangkalan:PC, atau papan pengembangan yang berjalan sepanjang waktu. Perannya adalah mengumpulkan data, melatih model prediksi hujan dan membuat prediksi

Alat:

1. USB to serial FTDI adapter FT232RL untuk memprogram Arduino Pro Mini

2. Arduino IDE

3. Bor

4. Mata gergaji halus

5. Obeng

6. Besi solder

7. Pemotong kawat

Keterampilan:

1. Solder, cek tutorial ini

2. Pemrograman arduino dasar

3. Konfigurasi layanan Linux, instalasi paket

4. Beberapa keterampilan pemrograman

Langkah 2:Membangun Stasiun Cuaca

Stasiun cuaca terdiri dari rangkaian komponen berikut:

1. kotak dengan panel surya yang direkatkan

2 . PCB dengan elektronik di dalamnya

3. tempat baterai juga di dalam

4. BME280 serta sensor cahaya dan hujan di bagian luar

1. Kotak membutuhkan 4 lubang, satu untuk kabel panel surya, tiga lainnya untuk sensor yang akan ditempatkan di luar. Pertama bor keseluruhannya, mereka harus cukup besar agar kabel pria-wanita menonjol dan masuk ke sensor. Setelah semuanya dibor, rekatkan panel ke salah satu sisi kotak dan ambil kabelnya melalui lubang di dalamnya

2. PCB akan menampung arduino, HC-12, regulator 3.3V, dioda, transistor, resistor, dan dua KF301-2P

  • solder dulu dua konektor PCB female pada PCB untuk arduino, solder konektor PCB male ke arduino dan letakkan arduino pada PCB
  • Led arduino harus dilepas atau setidaknya salah satu pinnya. ini sangat penting karena led akan menarik sejumlah besar daya. Hati-hati jangan sampai merusak komponen lain
  • solder transistor, resistor, dan regulator 3.3V
  • solder kedua KF301-2P. Satu untuk panel surya, yang lain untuk tempat baterai
  • solder tiga konektor PCB wanita:untuk sensor cahaya, BME280, dan sensor hujan
  • solder kabel kecil untuk menghubungkan semua komponen PCB (periksa gambar dan skema fritzing)

3. tempatkan 3 baterai AAA NiMH yang terisi daya di dalam dudukan dan letakkan di dalam kotak, sambungkan kabel ke konektor KF301-2P

4. sambungkan BME280 dan sensor cahaya dari luar kotak ke konektor pria yang sesuai

Untuk sensor hujan, solder tiga kabel (Gnd, Vcc, sinyal) ke sana, dan ke sisi lain solder pin jantan yang akan masuk ke dalam kotak ke konektor jantan yang sesuai

Hal terakhir adalah menempatkan stasiun ke posisi akhir. Saya telah memilih posisi yang terlindung dari hujan dan salju. Saya telah memilih kabel yang lebih panjang untuk sensor hujan dan menempatkannya secara terpisah di tengah hujan dengan penyangga yang stabil. Untuk kotak utama saya telah memilih jenis selotip khusus dengan perekat (periksa gambar) tetapi apa pun yang menahan kotak itu bisa digunakan.

sketch.fzz

Langkah 3:Kode Arduino

Dalam langkah ini Anda akan mempelajari pustaka eksternal apa yang diperlukan, kami meninjau kode dan cara kerjanya dan tentu saja Anda dapat mengunduh atau menyalin-tempelnya ke Arduino IDE dan mengunggahnya ke stasiun cuaca.

Peran stasiun cuaca adalah mengirimkan data ke stasiun pangkalan setiap 10 menit tentang sensornya.

Pertama mari kita jelaskan apa yang dilakukan program stasiun cuaca:

1. membaca data sensor (kelembaban, suhu, tekanan, hujan, cahaya, tegangan)

2. mentransmisikan data yang dikodekan melalui jalur serial perangkat lunak kedua.

Data yang dikodekan terlihat seperti ini:

H1:78|T1:12|PS1:1022|L1:500|R1:0|V1:4010|  

Pernyataan di atas akan berarti bahwa:kelembaban dari stasiun "1" adalah 78 persen, suhu dari stasiun 1 adalah 12 derajat, tekanan 1022 bar, tingkat cahaya 500 lux, hujan 0, dan tegangan 4010 milivolt

3. matikan komponen tambahan:sensor dan perangkat komunikasi

4. menempatkan arduino dalam mode tidur selama 10 menit (ini akan membuatnya mengkonsumsi kurang dari 50 microamps)

5. nyalakan komponen dan ulangi langkah 1 - 4

Satu tweak ekstra kecil di sini, jika level tegangan di atas 4,2 V arduino akan menggunakan fungsi tidur normal "penundaan (milidetik)". Ini akan sangat meningkatkan konsumsi daya dan menurunkan tegangan dengan cepat. Ini secara efektif mencegah panel surya mengisi baterai secara berlebihan.

Anda bisa mendapatkan kode dari repositori Github saya di sini:https://github.com/danionescu0/home-automation/tre...

Atau salin dan tempel dari bawah, dengan cara apa pun hapus saja baris dengan "transmitSenzorData("V", sensor.voltage);"

#include "LowPower.h"
#include "SoftwareSerial.h"#include "Wire.h"#include "Adafruit_Sensor.h"#include "Adafruit_BME280.h"#include "BH1750.h "SoftwareSerial serialComm(4, 5); // RX, TXAdafruit_BME280 bme; BH1750 lightMeter;const byte rainPin =A0;byte sensorCode =1;/** * level voltase yang akan memutar mikrokontroler dalam mode deep sleep alih-alih sleep biasa */int voltageDeepSleepThreshold =4200; const byte peripherialsPowerPin =6;char buffer[] ={' ',' ',' ',' ',' ',' ',' '};struct sensorData { kelembaban byte; int suhu; byte hujan; tekanan int; tegangan panjang; int cahaya; };sensorData sensor;pengaturan kosong() { Serial.begin(9600); serialComm.begin(9600); pinMode(PeriferalPowerPin, OUTPUT); digitalWrite(PeriferalPowerPin, TINGGI); penundaan (500); if (!bme.begin()) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1) { customSleep(100); } } Serial.println("Inisialisasi selesai dengan sukses"); penundaan (50); digitalWrite(PeriferalPowerPin, TINGGI);}void loop() { updateSenzors(); mengirimkanData(); kebiasaanTidur(75); }void updateSenzors() { bme.begin(); lightMeter.begin(); penundaan (300); sensor.temperature =bme.readTemperature(); sensor.tekanan =bme.readPressure() / 100.0F; sensor.kelembaban =bme.readHumidity(); sensor.light =lightMeter.readLightLevel(); sensor.voltage =readVcc(); sensor.rain =readRain();}void transmitData(){ emptyIncommingSerialBuffer(); Serial.print("Temp:");Serial.println(sensors.temperature); Serial.print("Humid:");Serial.println(sensors.humidity); Serial.print("Tekanan:");Serial.println(sensor.tekanan); Serial.print("Cahaya:");Serial.println(sensor.cahaya); Serial.print("Tegangan:");Serial.println(sensor.tegangan); Serial.print("Hujan:");Serial.println(sensors.rain); transmitSenzorData("T", sensor.temperature); transmitSenzorData("H", sensor.humidity); mengirimkanSenzorData("PS", sensor.tekanan); transmitSenzorData("L", sensor.light); transmitSenzorData("V", sensor.voltage); transmitSenzorData("R", sensor.rain);}void emptyIncommingSerialBuffer(){ while (serialComm.available()> 0) { serialComm.read(); penundaan (5); }}void transmitSenzorData(String type, int value){ serialComm.print(type); serialComm.print(sensorCode); serialComm.print(":"); serialComm.print(nilai); serialComm.print("|"); delay(50);}void customSleep(panjang delapanSecondCycles){ if (sensors.voltage> voltageDeepSleepThreshold) { delay(eightSecondCycles * 8000); kembali; } digitalWrite (periferalPowerPin, RENDAH); for (int i =0; i

Sebelum mengupload kode, download dan install library arduino berikut:

* Pustaka BH1750:https://github.com/claws/BH1750 * Pustaka LowPower:https://github.com/rocketscream/Low-Power

* Pustaka Sensor Adafruit:https://github.com/adafruit/Adafruit_Sensor

* Pustaka Adafruit BME280:https://github.com/adafruit/Adafruit_Sensor

Jika Anda tidak tahu bagaimana melakukannya, lihat tutorial ini.

Langkah 4:Mempersiapkan Stasiun Pangkalan

Pemancar akan terdiri dari komputer linux (desktop, laptop, atau papan pengembangan) dengan HC-12 USB modul terpasang. Komputer harus selalu menyala untuk mengumpulkan data setiap 10 menit dari stasiun.

Saya telah menggunakan laptop saya dengan Ubuntu 18.

Langkah-langkah instalasi:

1. Instal anaconda. Anaconda adalah pengelola paket Python dan akan memudahkan kita untuk bekerja dengan dependensi yang sama. Kami akan dapat mengontrol versi Python, dan setiap versi paket

Jika Anda tidak tahu cara menginstalnya, lihat ini:https://www.digitalocean.com/community/tutorials/h... tutorial dan ikuti langkah 1 - 8

2. Instal mongoDb. MongoDb akan menjadi database utama kami untuk proyek ini. Ini akan menyimpan data tentang semua deret waktu sensor. Ini tanpa skema dan untuk tujuan kami mudah digunakan.

Untuk langkah-langkah instalasi, lihat halaman mereka:https://docs.mongodb.com/v3.4/tutorial/install-mon...

Saya telah menggunakan versi lama mongoDb 3.4.6, jika Anda mengikuti tutorial di atas, Anda akan mendapatkan hal itu. Pada prinsipnya itu harus bekerja dengan versi terbaru.

[Opsional] tambahkan indeks pada bidang tanggal:

cuaca luwak db.weather_station.createIndex({"date" :1}) 

3. Unduh proyek dari sini:https://github.com/danionescu0/home-automation. Kami akan menggunakan folder prediksi cuaca

sudo apt-get install gitgit clone https://github.com/danionescu0/home-automation.gi... 

4. Buat dan konfigurasikan lingkungan anaconda:

cd weather-predict # buat lingkungan anaconda bernama "cuaca" dengan python 3.6.2conda create --name weather python=3.6.2 # aktifkan environmentconda aktifkan cuaca# instal semua paket pip install -r requirements.txt  

Ini akan membuat lingkungan anaconda baru dan menginstal paket yang diperlukan. Beberapa paketnya adalah:

Keras (lapisan jaringan saraf tingkat tinggi, dengan perpustakaan ini kami akan membuat semua prediksi jaringan saraf kami)

pandas (alat yang berguna untuk memanipulasi data, kami akan menggunakannya secara berlebihan)

pymongo (driver python mongoDb)

sklearn (penambangan data dan alat analisis data)

Konfigurasikan proyek

File konfigurasi terletak di folder prediksi cuaca dan diberi nama config.py

1. jika Anda menginstal MongoDb dari jarak jauh atau pada port yang berbeda, ubah "host" atau "port" di

mongodb ={ 'host':'localhost', 'port':27017}... 

2. Sekarang kita perlu memasang adaptor serial USB HC-12. Sebelum dijalankan:

ls -l /dev/tty* 

dan Anda akan mendapatkan daftar perangkat yang terpasang.

Sekarang masukkan HC-12 di port USB dan jalankan perintah yang sama lagi. Ini harus menjadi satu entri baru dalam daftar itu, adaptor serial kami. Sekarang ubah port adaptor di konfigurasi jika perlu

serial ={ 'port':'/dev/ttyUSB0', 'baud_rate':9600} 

Entri konfigurasi lainnya adalah beberapa jalur default file, tidak perlu ada perubahan di sana.

Langkah 5:Gunakan Stasiun Cuaca dalam Latihan

Di sini kita akan membahas hal-hal dasar tentang mengimpor data pengujian saya, menjalankan beberapa pengujian, menyiapkan data Anda sendiri, menampilkan beberapa grafik, dan menyiapkan email dengan prediksi untuk beberapa jam ke depan.

Jika Anda ingin tahu lebih banyak tentang cara kerjanya, lihat langkah berikutnya "Bagaimana cara kerjanya"

Mengimpor data saya yang sudah dikumpulkan

MongoDb hadir dengan perintah cli untuk mengimpor data dari json:

mongoimport -d weather -c weather_station --file sample_data/weather_station.json 

Ini akan mengimpor file dari data sampel ke database "cuaca" dan koleksi "titik data"

Peringatan di sini, jika Anda menggunakan data yang saya kumpulkan, dan menggabungkannya dengan data lokal baru Anda, akurasinya mungkin turun karena perbedaan kecil dalam perangkat keras (sensor) dan pola cuaca lokal.

Mengumpulkan data baru

Salah satu peran stasiun pangkalan adalah menyimpan data yang masuk dari stasiun cuaca ke dalam database untuk diproses nanti. Untuk memulai proses yang mendengarkan port serial dan menyimpannya di database, jalankan saja:

conda aktifkan weatherpython serial_listener.py# setiap 10 menit Anda akan melihat data dari stasiun cuaca masuk :[Sensor:type(temperature), value(14.3)][Sensor:type(pressure), value( 1056.0)]... 

Membuat model prediksi

Saya akan menganggap Anda telah mengimpor data saya atau "menjalankan skrip selama beberapa tahun" untuk mengumpulkan data pribadi Anda, jadi dalam langkah ini kami akan memproses data untuk membuat model yang digunakan untuk memprediksi hujan di masa mendatang.

conda aktifkan weatherpython train.py --days_behind 600 --test-file-percent 10 --datapoints-behind 8 --hour-granularity 6 

* Parameter pertama --days_behind berarti berapa banyak data ke masa lalu yang harus diproses skrip. Ini diukur dalam hari

* --test-file-percent berarti berapa banyak data yang harus dipertimbangkan untuk tujuan pengujian, ini adalah langkah reguler dalam algoritme pembelajaran mesin

* --hour-granularity pada dasarnya berarti berapa jam ke depan kita akan menginginkan prediksi

* --datapoints-behind parameter ini akan dibahas lebih lanjut ke bagian selanjutnya

Melihat beberapa bagan data dengan semua sensor stasiun cuaca

Katakanlah selama 10 hari terakhir:

conda mengaktifkan grafik python cuaca --days-behind 10 

Memprediksi apakah akan hujan pada periode berikutnya

Kami akan memprediksi apakah akan turun hujan dan mengirimkan email pemberitahuan

conda aktifkan python cuaca predict.py --datapoints-behind 8 --hour-granularity 6 --from-addr a_gmail_address --from-password gmail_password --to-addr a_email_destination 

Jalankan prediksi batch pada data pengujian:

python predict_batch.py ​​-f sample_data/test_data.csv 

Penting untuk menggunakan parameter yang sama seperti pada skrip kereta di atas.

Agar notifikasi email berfungsi, masuk ke akun gmail Anda dan Nyalakan Izinkan aplikasi yang kurang aman. Ketahuilah bahwa ini memudahkan orang lain untuk mendapatkan akses ke akun Anda.

Anda memerlukan dua alamat email, alamat gmail dengan opsi di atas diaktifkan, dan alamat lain tempat Anda akan menerima pemberitahuan.

Jika Anda ingin menerima notifikasi setiap jam, letakkan skrip di crontab

Untuk melihat bagaimana semua ini mungkin, periksa langkah selanjutnya

Langkah 6:Bagaimana Cara Kerjanya

Pada langkah terakhir ini kita akan membahas beberapa aspek arsitektur proyek ini:

1. Ikhtisar proyek, kita akan membahas arsitektur umum dan teknologi yang terlibat

2. Konsep dasar pembelajaran mesin

3. Bagaimana data disiapkan (langkah paling penting)

4. Cara kerja API pembungkus jaringan saraf yang sebenarnya (Keras)

5. Peningkatan di masa mendatang

Saya akan mencoba memberikan beberapa contoh kode di sini tetapi perlu diingat, bahwa itu bukan 100% kode dari proyek. Dalam proyek itu sendiri kodenya sedikit lebih rumit dengan kelas dan struktur

1. Ikhtisar proyek, kita akan membahas arsitektur umum dan teknologi yang terlibat

Seperti yang kita bicarakan sebelumnya, proyek ini memiliki dua bagian terpisah. Stasiun cuaca itu sendiri yang hanya berfungsi mengumpulkan dan mengirimkan data. Dan stasiun pangkalan tempat semua pelatihan dan prediksi pengumpulan akan terjadi.

Keuntungan pemisahan dari stasiun cuaca dan stasiun pangkalan:

  • kebutuhan daya, jika stasiun cuaca juga dapat memproses data, itu akan membutuhkan daya yang besar, mungkin panel surya besar atau sumber daya permanen
  • portabilitas, karena ukurannya yang kecil, stasiun cuaca dapat mengumpulkan data dari jarak beberapa ratus meter dan Anda dapat dengan mudah mengubah tempatnya jika diperlukan
  • skalabilitas, Anda dapat meningkatkan akurasi prediksi dengan membangun lebih dari satu stasiun cuaca dan menyebarkannya sekitar beberapa ratus meter
  • biaya rendah, karena ini adalah perangkat murah, Anda dapat dengan mudah membuat perangkat lain jika ada yang hilang atau dicuri

Pilihan basis data . Saya memilih mongoDb karena fiturnya bagus:tanpa skema, gratis, dan mudah digunakan API

Setiap kali data sensor diterima, data disimpan dalam database, entri datanya akan terlihat seperti ini:

{ "_id" :"04_27_2017_06_17", "kelembaban" :65, "tanggal" :ISODate("2017-04-27T06:17:18Z"), "tekanan" :1007, "suhu" :9, "hujan" :0, "cahaya" :15} 

Basis data menyimpan data dalam format BSON (mirip dengan JSON) sehingga mudah dibaca dan digunakan. Saya telah mengumpulkan data di bawah pengenal yang berisi tanggal yang diformat sebagai string ke menit, jadi pengelompokan terkecil di sini adalah menit.

Stasiun cuaca (saat bekerja dengan benar) akan mengirimkan titik data setiap 10 menit. Titik data adalah kumpulan nilai "tanggal", "kelembaban", "tekanan", "suhu", "hujan", dan "cahaya".

Pemrosesan data dan jaringan saraf pilihan teknologi

Saya telah memilih Python untuk backend karena banyak inovasi besar dalam jaringan saraf ditemukan di Python. Komunitas yang berkembang dengan banyak repositori Github, blog tutorial, dan buku siap membantu.

* Untuk bagian pemrosesan data saya menggunakan Panda (https://pandas.pydata.org/ ) . Panda membuat bekerja dengan data menjadi mudah. Anda dapat memuat tabel dari CSV, Excel, struktur data Python dan menyusunnya kembali, menghapus kolom, menambahkan kolom, mengindeks per kolom, dan banyak transformasi lainnya.

* Untuk bekerja dengan jaringan saraf saya telah memilih Keras (https://keras.io/). Keras adalah pembungkus jaringan saraf tingkat tinggi di atas API tingkat yang lebih rendah seperti Tensorflow dan seseorang dapat membangun jaringan saraf multi-lapisan dengan selusin baris kode atau lebih. Ini adalah keuntungan besar karena kita dapat membangun sesuatu yang berguna di atas karya besar orang lain. Nah, ini adalah hal dasar dari pemrograman, buat di blok bangunan lain yang lebih kecil.

2. Konsep dasar pembelajaran mesin

Cakupan tutorial ini bukan untuk mengajarkan pembelajaran mesin, tetapi hanya untuk menguraikan salah satu kasus penggunaan yang mungkin dan bagaimana kita dapat menerapkannya secara praktis ke kasus penggunaan ini.

Jaringan syaraf tiruan adalah struktur data yang menyerupai sel-sel otak yang disebut neuron. Ilmu pengetahuan menemukan bahwa otak memiliki sel-sel khusus bernama neuron yang berkomunikasi dengan neuron lain melalui impuls listrik melalui "garis" yang disebut akson. Jika dirangsang cukup (dari banyak neuron lain), neuron akan memicu impuls listrik lebih jauh di "jaringan" ini merangsang neuron lain. Ini tentu saja merupakan penyederhanaan proses, tetapi pada dasarnya algoritme komputer mencoba mereplikasi proses biologis ini.

Dalam jaringan saraf komputer setiap neuron memiliki "titik pemicu" di mana jika dirangsang di atas titik itu akan menyebarkan rangsangan ke depan, jika tidak tidak. Untuk ini setiap neuron yang disimulasikan akan memiliki bias, dan setiap akson memiliki bobot. Setelah inisialisasi nilai-nilai ini secara acak, proses yang disebut "belajar" dimulai. Artinya, dalam satu lingkaran, algoritme akan melakukan langkah-langkah ini:

  • merangsang neuron input
  • menyebarkan sinyal melalui lapisan jaringan sampai neuron keluaran
  • baca neuron keluaran dan bandingkan hasilnya dengan hasil yang diinginkan
  • Ubah bobot akson untuk hasil yang lebih baik di lain waktu
  • mulai lagi sampai jumlah loop tercapai

Jika Anda ingin mengetahui lebih detail tentang proses ini, Anda dapat membaca artikel ini:https://mattmazur.com/2015/03/17/a-step-by-step-ba.... Ada juga banyak buku dan tutorial di luar sana.

Satu hal lagi, di sini kita akan menggunakan metode pembelajaran terawasi. Itu berarti kami akan mengajarkan algoritme tentang input dan output juga, sehingga dengan serangkaian input baru, ia dapat memprediksi output.

3. Bagaimana data disiapkan (langkah terpenting)

Dalam banyak pembelajaran mesin dan masalah jaringan saraf, persiapan data adalah bagian yang sangat penting dan akan mencakup:

  • dapatkan data mentahnya
  • pembersihan data:ini berarti menghapus nilai yatim, penyimpangan, atau anomali lainnya
  • pengelompokan data:mengambil banyak titik data dan mengubahnya menjadi titik data gabungan
  • peningkatan data:menambahkan aspek lain dari data yang berasal dari data sendiri, atau dari sumber eksternal
  • membagi data dalam data latih dan uji
  • bagi setiap data kereta dan uji menjadi input dan output. Biasanya masalah akan memiliki banyak masukan dan sedikit keluaran
  • menskalakan ulang data sehingga antara 0 dan 1 (ini akan membantu jaringan menghilangkan bias nilai tinggi/rendah)

Mendapatkan data mentah

Dalam kasus kami, mendapatkan data untuk MongoDb dengan python sangat mudah. Mengingat pengumpulan titik data kami, hanya baris kode ini yang akan dilakukan

client =MongoClient(host, port).cuaca.datapoints kursor =client.find( {'$and' :[ {'date' :{'$gte' :start_date}}, {'date' :{'$lte' :end_date}} ]} )data =daftar(kursor).. 

Pembersihan data

Nilai kosong dalam kerangka data dibuang

dataframe =dataframe.dropna() 

Pengelompokan data &penyempurnaan data

This is a very important step, the many small datapoins will be grouped into intervals of 6 hours. For each group several metrics will be calculated on each of the sensors (humidity, rain, temperature, light, pressure)

  • min value
  • max value
  • mean
  • 70, 90, 30, 10 percentiles
  • nr of times there has been a rise in a sensor
  • nr of times there has been a fall in a sensor
  • nr of times there has been steady values in a sensor

All of these things will give the network information for a datapoint, so for each of the 6 hours intervals these things will be known.

From a dataframe that looks like this:

_id date humidity light pressure rain temperature 04_27_2017_03_08 2017-04-27 03:08:36 67.0 0.0 1007.0 0.0 11.004_27_2017_03_19 2017-04-27 03:19:05 66.0 0.0 1007.0 0.0 11.004_27_2017_03_29 2017-04-27 03:29:34 66.0 0.0 1007.0 0.0 11.0  

And the transformation will be:"

_id date humidity_10percentile humidity_30percentile humidity_70percentile humidity_90percentile humidity_avg ... temperature_avg temperature_fall temperature_max temperature_min temperature_rise temperature_steady ... 04_27_2017_0 2017-04-27 03:08:36 59.6 60.8 63.2 66.0 62.294118 ... 10.058824 2 11.0 9.0 1 1404_27_2017_1 2017-04-27 06:06:50 40.3 42.0 60.0 62.0 50.735294 ... 14.647059 3 26.0 9.0 11 2004_27_2017_2 2017-04-27 12:00:59 36.0 37.0 39.8 42.0 38.314286 ... 22.114286 1 24.0 20.0 5 29  

After this a new column named "has_rain" will be added. This will be the output (our predicted variable). Has rain will be 0 or 1 depending if the rain average is above a threshold (0.1). With pandas it's as simple as:

dataframe.insert(loc=1, column='has_rain', value=numpy.where(dataframe['rain_avg']> 0.1, 1, 0)) 

Data cleanup (again)

- we'll drop the date column because it's no use to us, and also remove datapoints where the minimum temperature is below 0 because our weather station it doesn't have a snow sensor, so we won't be able to measure if it snowed

dataframe =dataframe.drop(['date'], axis=1)dataframe =dataframe[dataframe['temperature_min']>=0] 

Data enhancing

Because data in the past might influence our prediction of the rain, we need for each of the dataframe rows to add columns reference to the past rows. This is because each of the row will serve as a training point, and if we want the prediction of the rain to take into account previous datapoints that's exactly what we should do:add more columns for datapoints in the past ex:

_id has_rain humidity_10percentile humidity_30percentile humidity_70percentile humidity_90percentile ... temperature_steady_4 temperature_steady_5 temperature_steady_6 temperature_steady_7 temperature_steady_8 ... 04_27_2017_3 0 36.0 44.8 61.0 63.0 ... NaN NaN NaN NaN NaN04_28_2017_0 0 68.0 70.0 74.0 75.0 ... 14.0 NaN NaN NaN NaN04_28_2017_1 0 40.0 45.0 63.2 69.0 ... 20.0 14.0 NaN NaN NaN04_28_2017_2 0 34.0 35.9 40.0 41.0 ... 29.0 20.0 14.0 NaN NaN04_28_2017_3 0 36.1 40.6 52.0 54.0 ... 19.0 29.0 20.0 14.0 NaN04_29_2017_0 0 52.0 54.0 56.0 58.0 ... 26.0 19.0 29.0 20.0 14.004_29_2017_1 0 39.4 43.2 54.6 57.0 ... 18.0 26.0 19.0 29.0 20.004_29_2017_2 1 41.0 42.0 44.2 47.0 ... 28.0 18.0 26.0 19.0 29.0  

So you see that for every sensor let's say temperature the following rows will be added:"temperature_1", "temperature_2".. meaning temperature on the previous datapoint, temperature on the previous two datapoints etc. I've experimented with this and I found that a optimum number for our 6 hour groupings in 8. That means 8 datapoints in the past (48 hours). So our network learned the best from datapoins spanning 48 hours in the past.

Data cleanup (again)

As you see, the first few columns has "NaN" values because there is nothing in front of them so they should be removed because they are incomplete.

Also data about current datapoint should be dropped, the only exception is "has_rain". the idea is that the system should be able to predict "has_rain" without knowing anything but previous data.

Splitting the data in train and test data

This is very easy due to Sklearn package:

from sklearn.model_selection import train_test_split ...main_data, test_data =train_test_split(dataframe, test_size=percent_test_data) ... 

This will split the data randomly into two different sets

Split each of the train and test data into inputs and outputs

Presuming that our "has_rain" interest column is located first

X =main_data.iloc[:, 1:].valuesy =main_data.iloc[:, 0].values  

Rescale the data so it's between 0 and 1

Again fairly easy because of sklearn

from sklearn.preprocessing import StandardScalerfrom sklearn.externals import joblib..scaler =StandardScaler()X =scaler.fit_transform(X) ...# of course we should be careful to save the scaled model for later reusejoblib.dump(scaler, 'model_file_name.save')  

4. How the actual neural network wrapper API works (Keras)

Building a multi layer neural network with Keras is very easy:

from keras.models import Sequentialfrom keras.layers import Densefrom keras.layers import Dropout ...input_dimensions =X.shape[1] optimizer ='rmsprop'dropout =0.05model =Sequential()inner_nodes =int(input_dimensions / 2)model.add(Dense(inner_nodes, kernel_initializer='uniform', activation='relu', input_dim=input_dimensions))model.add(Dropout(rate=dropout))model.add(Dense(inner_nodes, kernel_initializer='uniform', activation='relu'))model.add(Dropout(rate=dropout))model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))model.compile(optimizer=optimizer, loss='mean_absolute_error', metrics=['accuracy']) model.fit(X, y, batch_size=1, epochs=50)...# save the model for later useclassifier.save('file_model_name') 

So what does this code mean? Here we're building a sequential model, that means sequentially all the layers will be evaluated.

a) we declare the input layer (Dense), here all the inputs from our dataset will be initializedm so the "input_dim" parameter must be equal to the row length

b) a Dropout layer is added. To understand the Dropout first we must understand what "overfitting" means:it's a state in which the network has learned too much particularities for a specific dataset and will perform badly when confronted to a new dataset. The dropout layer will disconnect randomly neurons at each iteration so the network won't overfit.

c) another layer of Dense is added

d) another Dropout

e) the last layer is added with one output dimension (it will predict only yes/no)

f) the model is "fitted" that means the learning process will begin, and the model will learn

Other parameters here:

  • activation functions (sigmoid, relu). This are functions that dictate when the neuron will transmit it's impulse further in the network. There are many, but sigmoid and relu are the most common. Check out this link for more details:https://towardsdatascience.com/activation-function...
  • kernel_initializer function (uniform). This means that all the weights are initialized with random uniform values
  • loss function (mean_absolute_error). This function measures the error comparing the network predicted result versus the ground truth. There are many alternatives:https://keras.io/losses/
  • metrics function (accuracy). It measures the performance of the model
  • optimiser functions (rmsprop). It optimizes how the model learn through backpropagation.
  • batch_size. Number of datapoints to take once by Keras before applying optimizer function
  • epochs:how many times the process it's started from 0 (to learn better)

There is no best configuration for any network or dataset, all these parameters can an should be tuned for optimal performance and will make a big difference in prediction success.

5. Future improvements

Let's start from the weather station , I can see a lot of improving work to be done here:

  • add a wind speed / direction sensor. This could be a very important sensor that i'm missing in my model
  • experiment with UV rays, gas and particle sensors
  • add at least two stations in the zone for better data (make some better averages)
  • collect a few more years of data, i've experimented with just a year and a half

Some processing improvements:

  • try to incorporate data from other sources into the model. You can start to import wind speed data and combine with the local station data for a better model. This website offers historical data:https://www.wunderground.com/history/
  • optimize the Keras model better by adjusting:layers, nr of neurons in layers, dropout percents, metrics functions, optimiser functions, loss functions, batch size, learning epochs
  • try other model architectures, for example i've experimented with LSTM (long short term memory) but it gived slightly poorer results)

To try different parameters on the learning model you can use

python train.py --days_behind 600 --test-file-percent 10 --datapoints-behind 6 --hour-granularity 6 --grid-search 

This will search through different "batch_size", "epoch", "optimizer" and "dropout" values, evaluate all and print out the best combination for your data.

If you have some feedback on my work please share it, thanks for staying till the end of the tutorial!

Step 7:Bonus:Using an Official Weather Dataset

I was wondering if I can get better results with a more reliable weather station, so i've searched a bit, and i've came across "Darksky AP I" (https://darksky.net/dev), this is a great tool that provides current and historical weather data with many more sensor data:

  • temperature
  • humidity
  • pressure
  • wind speed
  • wind gust
  • ub index
  • visibilitySo this beeing data from an official weather station, and having more parameters I thought it should perform better so i've gave it a try. To replicate my findings:

1.Download the data from darsky or import my MongoDb collection:

a) Download

  • to download your self, first create an account in darsky and get the API key
  • replace the API key in download_import/config.py
  • also in the config replace the geographic coordonates for the location you want to predict the rain
  • in a console activate "weather" anaconda environment and run:
python download_import/darksky.py -d 1000 

- the free version of the API is limited to 1000 requests per day so if you want more data you need to wait for a longer time

b) Import my downloaded data for Bucharest city

- in a console run

mongoimport -d weather -c darksky --file sample_data/darksky.json  

2. When you train the model specify that it should run on "darksy" dataset

python train.py -d 2000 -p 20 -dp 4 -hg 6 --data-source darksky 

3. To see the results run predict batch script as before

python predict_batch.py -f sample_data/test_data.csv 

You'll see that the overall prediction percent has gone from about 80% to 90%. Also the prediction accuracy when accounting only rainy days has gone up.

So yes, the dataset really matters.

Kode

  • Cuplikan kode #2
  • Cuplikan kode #5
  • Code snippet #6
  • Code snippet #10
  • Code snippet #15
  • Code snippet #16
  • Code snippet #18
  • Code snippet #22
  • Code snippet #23
  • Code snippet #25
  • Code snippet #26
Cuplikan kode #2Teks biasa
#include "LowPower.h"
#include "SoftwareSerial.h"#include "Wire.h"#include "Adafruit_Sensor.h"#include "Adafruit_BME280.h"#include "BH1750.h"SoftwareSerial serialComm(4, 5); // RX, TXAdafruit_BME280 bme; BH1750 lightMeter;const byte rainPin =A0;byte sensorsCode =1;/** * voltage level that will pun the microcontroller in deep sleep instead of regular sleep */int voltageDeepSleepThreshold =4200; const byte peripherialsPowerPin =6;char buffer[] ={' ',' ',' ',' ',' ',' ',' '};struct sensorData { byte humidity; int temperature; byte rain; int pressure; long voltage; int light; };sensorData sensors;void setup() { Serial.begin(9600); serialComm.begin(9600); pinMode(peripherialsPowerPin, OUTPUT); digitalWrite(peripherialsPowerPin, HIGH); penundaan (500); if (!bme.begin()) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1) { customSleep(100); } } Serial.println("Initialization finished succesfully"); penundaan (50); digitalWrite(peripherialsPowerPin, HIGH);}void loop() { updateSenzors(); transmitData(); customSleep(75); }void updateSenzors() { bme.begin(); lightMeter.begin(); penundaan (300); sensors.temperature =bme.readTemperature(); sensors.pressure =bme.readPressure() / 100.0F; sensors.humidity =bme.readHumidity(); sensors.light =lightMeter.readLightLevel(); sensors.voltage =readVcc(); sensors.rain =readRain();}void transmitData(){ emptyIncommingSerialBuffer(); Serial.print("Temp:");Serial.println(sensors.temperature); Serial.print("Humid:");Serial.println(sensors.humidity); Serial.print("Pressure:");Serial.println(sensors.pressure); Serial.print("Light:");Serial.println(sensors.light); Serial.print("Voltage:");Serial.println(sensors.voltage); Serial.print("Rain:");Serial.println(sensors.rain); transmitSenzorData("T", sensors.temperature); transmitSenzorData("H", sensors.humidity); transmitSenzorData("PS", sensors.pressure); transmitSenzorData("L", sensors.light); transmitSenzorData("V", sensors.voltage); transmitSenzorData("R", sensors.rain);}void emptyIncommingSerialBuffer(){ while (serialComm.available()> 0) { serialComm.read(); penundaan (5); }}void transmitSenzorData(String type, int value){ serialComm.print(type); serialComm.print(sensorsCode); serialComm.print(":"); serialComm.print(value); serialComm.print("|"); delay(50);}void customSleep(long eightSecondCycles){ if (sensors.voltage> voltageDeepSleepThreshold) { delay(eightSecondCycles * 8000); kembali; } digitalWrite(peripherialsPowerPin, LOW); for (int i =0; i
Cuplikan kode #5Teks biasa
cd weather-predict # create anaconda environment named "weather" with python 3.6.2conda create --name weather python=3.6.2 # activate environmentconda activate weather# install all packages pip install -r requirements.txt 
Code snippet #6Plain text
mongodb ={ 'host':'localhost', 'port':27017}...
Code snippet #10Plain text
conda activate weatherpython serial_listener.py# every 10 minutes you should see data from the weather station coming in :[Sensor:type(temperature), value(14.3)][Sensor:type(pressure), value(1056.0)]...
Code snippet #15Plain text
{ "_id" :"04_27_2017_06_17", "humidity" :65, "date" :ISODate("2017-04-27T06:17:18Z"), "pressure" :1007, "temperature" :9, "rain" :0, "light" :15}
Code snippet #16Plain text
client =MongoClient(host, port).weather.datapoints cursor =client.find( {'$and' :[ {'date' :{'$gte' :start_date}}, {'date' :{'$lte' :end_date}} ]} )data =list(cursor)..
Code snippet #18Plain text
_id date humidity light pressure rain temperature 04_27_2017_03_08 2017-04-27 03:08:36 67.0 0.0 1007.0 0.0 11.004_27_2017_03_19 2017-04-27 03:19:05 66.0 0.0 1007.0 0.0 11.004_27_2017_03_29 2017-04-27 03:29:34 66.0 0.0 1007.0 0.0 11.0 
Code snippet #22Plain text
_id has_rain humidity_10percentile humidity_30percentile humidity_70percentile humidity_90percentile ... temperature_steady_4 temperature_steady_5 temperature_steady_6 temperature_steady_7 temperature_steady_8 ... 04_27_2017_3 0 36.0 44.8 61.0 63.0 ... NaN NaN NaN NaN NaN04_28_2017_0 0 68.0 70.0 74.0 75.0 ... 14.0 NaN NaN NaN NaN04_28_2017_1 0 40.0 45.0 63.2 69.0 ... 20.0 14.0 NaN NaN NaN04_28_2017_2 0 34.0 35.9 40.0 41.0 ... 29.0 20.0 14.0 NaN NaN04_28_2017_3 0 36.1 40.6 52.0 54.0 ... 19.0 29.0 20.0 14.0 NaN04_29_2017_0 0 52.0 54.0 56.0 58.0 ... 26.0 19.0 29.0 20.0 14.004_29_2017_1 0 39.4 43.2 54.6 57.0 ... 18.0 26.0 19.0 29.0 20.004_29_2017_2 1 41.0 42.0 44.2 47.0 ... 28.0 18.0 26.0 19.0 29.0 
Code snippet #23Plain text
from sklearn.model_selection import train_test_split ...main_data, test_data =train_test_split(dataframe, test_size=percent_test_data) ...
Code snippet #25Plain text
from sklearn.preprocessing import StandardScalerfrom sklearn.externals import joblib..scaler =StandardScaler()X =scaler.fit_transform(X) ...# of course we should be careful to save the scaled model for later reusejoblib.dump(scaler, 'model_file_name.save') 
Code snippet #26Plain text
from keras.models import Sequentialfrom keras.layers import Densefrom keras.layers import Dropout ...input_dimensions =X.shape[1] optimizer ='rmsprop'dropout =0.05model =Sequential()inner_nodes =int(input_dimensions / 2)model.add(Dense(inner_nodes, kernel_initializer='uniform', activation='relu', input_dim=input_dimensions))model.add(Dropout(rate=dropout))model.add(Dense(inner_nodes, kernel_initializer='uniform', activation='relu'))model.add(Dropout(rate=dropout))model.add(Dense(1, kernel_initializer='uniform', activation='sigmoid'))model.compile(optimizer=optimizer, loss='mean_absolute_error', metrics=['accuracy']) model.fit(X, y, batch_size=1, epochs=50)...# save the model for later useclassifier.save('file_model_name')
Github
https://github.com/claws/BH1750https://github.com/claws/BH1750
Github
https://github.com/rocketscream/Low-Powerhttps://github.com/rocketscream/Low-Power
Github
https://github.com/adafruit/Adafruit_Sensorhttps://github.com/adafruit/Adafruit_Sensor
Github
https://github.com/adafruit/Adafruit_BME280_Libraryhttps://github.com/adafruit/Adafruit_BME280_Library
Github
https://github.com/danionescu0/home-automationhttps://github.com/danionescu0/home-automation

Skema

sketch_KAtDa2VReF.fzz
Weather station arduino sketch
https://github.com/danionescu0/home-automation/tree/master/arduino-sketches/weatherStation

Proses manufaktur

  1. Sensor Suhu Python dan Raspberry Pi
  2. Konsol Pengeditan Photoshop DIY menggunakan Arduino Nano RP 2040
  3. Python Ganti Nama File dan Direktori menggunakan os.rename()
  4. Sistem Kehadiran Menggunakan Arduino dan RFID dengan Python
  5. Kontrol Jarak Jauh Universal menggunakan Arduino, 1Sheeld, dan Android
  6. Voltmeter DIY Menggunakan Arduino dan Smartphone
  7. Sensor Detak Jantung Inframerah DIY menggunakan Arduino
  8. Pengukuran Frekuensi dan Siklus Tugas Menggunakan Arduino
  9. Voltmeter DIY dengan Arduino dan Tampilan Nokia 5110
  10. Sonar menggunakan arduino dan ditampilkan pada pemrosesan IDE