Started a preliminary jupyter notebook with comments. Updated README.
This commit is contained in:
parent
600333eeaf
commit
8eaa3abd5b
3 changed files with 356 additions and 2 deletions
141
README.md
141
README.md
|
@ -1,6 +1,6 @@
|
|||
See 420Project17fall.pdf
|
||||
|
||||
use this script to download the data files, because I'm not hosting them here.
|
||||
Use this script to download the data files, because I'm not hosting them here.
|
||||
|
||||
~~~~
|
||||
mkdir "data"
|
||||
|
@ -9,3 +9,142 @@ do
|
|||
wget "http://courses.cse.tamu.edu/daugher/misc/PPP/homeworks/data/${i}states.bin" -O "data/${i}.bin"
|
||||
done
|
||||
~~~~
|
||||
|
||||
I didn't include that as a shell script file because it's really better
|
||||
in general for one to see the shell code they're running before they just
|
||||
blindly trust a script to do what they want it to do.
|
||||
|
||||
# Setup
|
||||
|
||||
## Anaconda/Miniconda (optional)
|
||||
|
||||
For my implementation, I'm using a native Python 3 install on Linux.
|
||||
|
||||
However, if you want to be safe about preserving your Python environment
|
||||
(essentially, if you want to compartmentalize your Python install so if you
|
||||
mess up it won't affect your native Python environment), I suggest
|
||||
instead installing Anaconda or Miniconda and going through the following process
|
||||
from there in your terminal:
|
||||
|
||||
~~~
|
||||
conda create -n project420 python
|
||||
conda install -n project420 jupyter
|
||||
conda install -n project420 tensorflow
|
||||
conda install -n project420 keras
|
||||
~~~
|
||||
|
||||
You can replace project420 with whatever you want to call the environment.
|
||||
|
||||
After those are installed, when you want to activate that Python environment,
|
||||
(which you'll have to do if you open a new terminal window) type:
|
||||
~~~
|
||||
source activate project420
|
||||
~~~
|
||||
|
||||
## Installing natively
|
||||
|
||||
### Linux
|
||||
|
||||
If you would rather just install the necessary things to your native Python
|
||||
environment, then here are the things you will need if you're on Linux:
|
||||
|
||||
- TensorFlow (or equivalent backend for Keras)
|
||||
- Keras
|
||||
- Jupyter
|
||||
|
||||
I suggest installing them through your respective repository's repos if you can.
|
||||
|
||||
### Windows
|
||||
|
||||
Well... I didn't set up on Windows, but the packages you will need remain the same.
|
||||
|
||||
I would suggest considering using the native pip install method:
|
||||
|
||||
~~~
|
||||
pip install tensorflow
|
||||
pip install keras
|
||||
pip install jupyter
|
||||
~~~
|
||||
|
||||
# Getting Started
|
||||
|
||||
## Parsing the .bin files
|
||||
|
||||
Basically, we're being instructed to parse through these .bin files in order
|
||||
to get "states" of a 15-piece puzzle, illustrated in the project documentation.
|
||||
|
||||
Each of these n.bin files contains the corresponding states that are n many
|
||||
turns away from the solution. That part of the instruction is essential to
|
||||
understand before we go any further.
|
||||
To illustrate better: this means that 0.bin contains every state in which
|
||||
the puzzle is 0 moves away from being solved, and so on for each n.bin file.
|
||||
|
||||
In order to parse these binary files, we need to tell python to read in the
|
||||
file in binary mode and then we need to translate that binary to a hex string
|
||||
format. I've already written out some preliminary code that will do the for
|
||||
you in the included "test.py" script.
|
||||
|
||||
Just run:
|
||||
~~~
|
||||
python test.py
|
||||
~~~
|
||||
|
||||
and the output that you are given is the only state in the 0.bin file, which
|
||||
represents the state of the puzzle when it is solved.
|
||||
|
||||
There's a lot of terminology being thrown around in the documentation about
|
||||
what this hex string means, so I'm going to simplify it:
|
||||
|
||||
Each letter in the hex string represents a 4 bit integer.
|
||||
|
||||
We know that hexadecimal values can only range from 0 to f (or, at least,
|
||||
you should know considering you are a senior computer science major).
|
||||
|
||||
This means that every 4 bits that we read in correspond to a hexadecimal
|
||||
character, which represents a value from 0 to 15. These corresponding
|
||||
values map perfectly to our puzzle to represent which numbered tile is
|
||||
in which space. If we refer back to our documentation we see that the first
|
||||
row of the solved puzzle is "1, 2, 3 ,4", and the corresponding first 4
|
||||
hex characters of our string are "f, 2, 3, 4", and so on.
|
||||
|
||||
Now you may be questioning why this isn't exactly the same as our puzzle.
|
||||
This is where the concept of negative entropy can be explained. We don't
|
||||
need to define what the first place in our puzzle is because we can deduce
|
||||
it from what we already know. The puzzle only has 16 pieces, and we know
|
||||
where the other 15 pieces are, so what's left is the piece 1. We remove
|
||||
the first 4 bits because adding that information is simply unnecessary.
|
||||
|
||||
That much is explained to you now and I hope that can get you started
|
||||
on understanding what we need to do as far as parsing the bin files.
|
||||
|
||||
## Using Keras
|
||||
|
||||
There are a lot of comments in the included Jupyter Notebook in this
|
||||
github repo, but here's just how to get started and a brief explanation
|
||||
of what we're doing here.
|
||||
|
||||
First, you'll want to run jupyter notebook to see what we're doing.
|
||||
|
||||
Jupyter is a tool for python that runs an interactive HTTP server that
|
||||
can allow users to test python scripts and bits of python code as well
|
||||
as write reports in an interactive fashion, it's typically used for
|
||||
research, and what we're doing here will be much more helpful to be
|
||||
able to quickly run constantly and make modifications.
|
||||
|
||||
To run Jupyter, just type into a terminal:
|
||||
~~~
|
||||
jupyter notebook
|
||||
~~~
|
||||
|
||||
This will open an HTTP server that will then open a window in your
|
||||
current default browser allowing you to select a notebook to open
|
||||
from your filesystem.
|
||||
|
||||
Or, if you want to directly open the journal from command-line:
|
||||
~~~
|
||||
jupyter notebook neural_network.ipynb
|
||||
~~~
|
||||
|
||||
# Well there you go
|
||||
|
||||
I hope that helps you guys get started... LMK if you have more questions.
|
||||
|
|
215
neural_network.ipynb
Normal file
215
neural_network.ipynb
Normal file
|
@ -0,0 +1,215 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Using TensorFlow backend.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# If you're really new to python this code might be\n",
|
||||
"# a bit unreadable, but I tried to make it as simple\n",
|
||||
"# as possible.\n",
|
||||
"\n",
|
||||
"# Setting up our imported libraries.\n",
|
||||
"import numpy as np\n",
|
||||
"from keras.models import Sequential\n",
|
||||
"from keras.layers import Dense\n",
|
||||
"\n",
|
||||
"# We're going to use numpy for some easy\n",
|
||||
"# array functionality with keras, and keras\n",
|
||||
"# is our library for handling most of our neural network\n",
|
||||
"# stuff. That being said, you need to have some sort of\n",
|
||||
"# backend for keras to work with, such as the recommended\n",
|
||||
"# TensorFlow, which I'm using here.\n",
|
||||
"# Since keras uses those as a backend, you don't inherently\n",
|
||||
"# need to import it."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"240000\n",
|
||||
"240\n",
|
||||
"[[ 0.88203814 0.94907443 0.32403829 ..., 0.55091702 0.10493225\n",
|
||||
" 0.89821938]\n",
|
||||
" [ 0.02144088 0.15692337 0.99218119 ..., 0.42989668 0.70931057\n",
|
||||
" 0.61624769]\n",
|
||||
" [ 0.24650157 0.68008751 0.65118644 ..., 0.44870335 0.3114548\n",
|
||||
" 0.63668488]\n",
|
||||
" ..., \n",
|
||||
" [ 0.6794534 0.05525846 0.7217934 ..., 0.71333628 0.1438383\n",
|
||||
" 0.07574106]\n",
|
||||
" [ 0.11292803 0.19181161 0.89034259 ..., 0.60669516 0.11716027\n",
|
||||
" 0.76495791]\n",
|
||||
" [ 0.59152954 0.92534686 0.77183522 ..., 0.61204755 0.84179215\n",
|
||||
" 0.50034833]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Generating dummy data so I can understand how to input.\n",
|
||||
"data = np.random.random((1000,240))\n",
|
||||
"output = np.random.random((1000, 29))\n",
|
||||
"\n",
|
||||
"# Here's some printouts to see exactly what I'm doing here.\n",
|
||||
"print(data.size)\n",
|
||||
"print(data[0].size)\n",
|
||||
"print(data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Epoch 1/5\n",
|
||||
"1000/1000 [==============================] - 1s 626us/step - loss: 0.0922 - acc: 0.0370\n",
|
||||
"Epoch 2/5\n",
|
||||
"1000/1000 [==============================] - 0s 158us/step - loss: 0.0895 - acc: 0.0360\n",
|
||||
"Epoch 3/5\n",
|
||||
"1000/1000 [==============================] - 0s 149us/step - loss: 0.0884 - acc: 0.0340\n",
|
||||
"Epoch 4/5\n",
|
||||
"1000/1000 [==============================] - 0s 163us/step - loss: 0.0879 - acc: 0.0310\n",
|
||||
"Epoch 5/5\n",
|
||||
"1000/1000 [==============================] - 0s 165us/step - loss: 0.0877 - acc: 0.0340\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"<keras.callbacks.History at 0x7f852ccdb320>"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Sets up a Sequential model, Sequential is all\n",
|
||||
"# that should need to be used for this project,\n",
|
||||
"# considering that it will only be dealing with\n",
|
||||
"# a linear stack of layers of neurons.\n",
|
||||
"model = Sequential()\n",
|
||||
"\n",
|
||||
"# Adding layers to the model.\n",
|
||||
"\n",
|
||||
"# Dense is the type of layer I think, don't need\n",
|
||||
"# to look into this more since this is all I should\n",
|
||||
"# need to use.\n",
|
||||
"\n",
|
||||
"# units = the number of neurons for this layer.\n",
|
||||
"\n",
|
||||
"# activation = the activation function for this layer.\n",
|
||||
"# our project doc says to use hyperbolic tangent, so\n",
|
||||
"# I set this to tanh. Except for the output layer,\n",
|
||||
"# which I set to sigmoid.\n",
|
||||
"\n",
|
||||
"# input_dim = the dimension of the input list,\n",
|
||||
"# should only be set for the input layer.\n",
|
||||
"\n",
|
||||
"model.add(Dense(units=240, activation='tanh', input_dim=240))\n",
|
||||
"model.add(Dense(units=120, activation='tanh'))\n",
|
||||
"model.add(Dense(units=29, activation='sigmoid'))\n",
|
||||
"\n",
|
||||
"# Configure the learning process.\n",
|
||||
"# \n",
|
||||
"\n",
|
||||
"# optimizer = I'm just using \n",
|
||||
"# Stomchastic gradient descent for this,\n",
|
||||
"# remember that this uses essentially staggered\n",
|
||||
"# aggregation by step to calculate gradient\n",
|
||||
"# descent towards our target, which is faster\n",
|
||||
"# than doing all of the calculation together.\n",
|
||||
"\n",
|
||||
"# loss = the loss function, currently I'm using\n",
|
||||
"# mean squared error, but might change to\n",
|
||||
"# mean_absolute_percentage_error, considering\n",
|
||||
"# I think we're supposed to calculate cost\n",
|
||||
"# based on the percentage we are away from the\n",
|
||||
"# correct number of moves away from the solved state.\n",
|
||||
"\n",
|
||||
"# metrics = evaluation metrics...\n",
|
||||
"# I think all I care about is accuracy in this case,\n",
|
||||
"# if anything.\n",
|
||||
"\n",
|
||||
"model.compile(optimizer='sgd',\n",
|
||||
" loss='mean_squared_error',\n",
|
||||
" metrics=['accuracy'])\n",
|
||||
"\n",
|
||||
"# This is where we're configuring how we train the network:\n",
|
||||
"\n",
|
||||
"# data = the input sets of training data for this network,\n",
|
||||
"# in my case I'm unsure what exactly that will be.\n",
|
||||
"\n",
|
||||
"# output = the input sets of target data for the network,\n",
|
||||
"# I believe this should just be a set of the same size\n",
|
||||
"# as the training data all containing the number\n",
|
||||
"# of steps until being solved for each state... I think.\n",
|
||||
"\n",
|
||||
"# epochs = it seems like this is how many times this\n",
|
||||
"# training should be run...\n",
|
||||
"\n",
|
||||
"# batch_size = I'm pretty sure this directly correlates\n",
|
||||
"# to how many input sets we train per step.\n",
|
||||
"\n",
|
||||
"model.fit(data, output, epochs=5, batch_size=10)\n",
|
||||
"\n",
|
||||
"# Generating predictions should look like this:\n",
|
||||
"\n",
|
||||
"# predictions = model.predict(testing_data, batch_size=10)\n",
|
||||
"\n",
|
||||
"# I've commented it out since I don't have any real\n",
|
||||
"# data to predict yet."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.6.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
2
test.py
2
test.py
|
@ -1,4 +1,4 @@
|
|||
with open('data/0.bin', 'rb') as f:
|
||||
with open('data/1.bin', 'rb') as f:
|
||||
data = f.read()
|
||||
|
||||
print(hex(int.from_bytes(data, byteorder='little', signed=False)))
|
||||
|
|
Reference in a new issue