Some corrections
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -13,6 +13,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation(kotlin("test"))
|
testImplementation(kotlin("test"))
|
||||||
|
implementation("com.github.doyaaaaaken:kotlin-csv-jvm:1.6.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.test {
|
tasks.test {
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+47
-13
@@ -1,15 +1,49 @@
|
|||||||
|
import com.github.doyaaaaaken.kotlincsv.dsl.csvReader
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
var sepal_length_max = 0.0
|
||||||
|
var sepal_width_max = 0.0
|
||||||
|
var petal_length_max = 0.0
|
||||||
|
var petal_width_max = 0.0
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val model = Perceptron(3, arrayOf(), 2)
|
val file = File("/run/media/sweetbread/50AF29954CE66E9F/Coding/Kotlin/AI/src/main/resources/IRIS.csv")
|
||||||
model.teach(
|
val data: List<Iris> = csvReader().readAll(file).drop(1).map { Iris(it[0].toDouble(), it[1].toDouble(), it[2].toDouble(), it[3].toDouble(), it[4]) } .shuffled()
|
||||||
arrayOf(
|
data.forEach {
|
||||||
arrayOf(arrayOf(0.0, 0.0, 1.0), arrayOf(0.0, 0.0)),
|
if (it.sepal_length > sepal_length_max) sepal_length_max = it.sepal_length
|
||||||
arrayOf(arrayOf(0.0, 1.0, 0.0), arrayOf(1.0, 0.0)),
|
if (it.sepal_width > sepal_width_max) sepal_width_max = it.sepal_width
|
||||||
arrayOf(arrayOf(1.0, 0.0, 1.0), arrayOf(0.0, 1.0)),
|
if (it.petal_length > petal_length_max) petal_length_max = it.petal_length
|
||||||
arrayOf(arrayOf(1.0, 1.0, 1.0), arrayOf(1.0, 1.0))
|
if (it.petal_width > petal_width_max) petal_width_max = it.petal_width
|
||||||
), 10000
|
}
|
||||||
)
|
|
||||||
model.input(arrayOf(0.0, 0.0, 1.0)); println(model.output())
|
val model = Perceptron(arrayOf(
|
||||||
model.input(arrayOf(0.0, 1.0, 1.0)); println(model.output())
|
Layer(4),
|
||||||
model.input(arrayOf(1.0, 0.0, 0.0)); println(model.output())
|
Layer(4),
|
||||||
model.input(arrayOf(1.0, 1.0, 0.0)); println(model.output())
|
Layer(3, false)
|
||||||
|
))
|
||||||
|
println(model.output())
|
||||||
|
|
||||||
|
model.teach(data.subList(0, 50).map { it.data_field() }.toTypedArray(), 100, false)
|
||||||
|
data[100].data_field()[1].forEach { print(it.toInt()); print(" ") }
|
||||||
|
println()
|
||||||
|
model.input(data[100].data_field()[0]); println(model.output())
|
||||||
|
}
|
||||||
|
|
||||||
|
class Iris (
|
||||||
|
val sepal_length: Double,
|
||||||
|
val sepal_width: Double,
|
||||||
|
val petal_length: Double,
|
||||||
|
val petal_width: Double,
|
||||||
|
val species: String
|
||||||
|
) {
|
||||||
|
fun data_field(): Array<Array<Double>> {
|
||||||
|
return arrayOf(
|
||||||
|
arrayOf(sepal_length/sepal_length_max, sepal_width/sepal_width_max, petal_length/petal_length_max, petal_width/petal_width_max),
|
||||||
|
arrayOf(
|
||||||
|
if (species == "Iris-setosa") 1.0 else 0.0,
|
||||||
|
if (species == "Iris-versicolor") 1.0 else 0.0,
|
||||||
|
if (species == "Iris-virginica") 1.0 else 0.0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,124 +1,108 @@
|
|||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
class Perceptron (val input_n: Int, val hidden_n: Array<Int> = arrayOf(), val output_n: Int, val k: Double = 0.5) {
|
class Perceptron (private val layers: Array<Layer>, private val k: Double = 0.5) {
|
||||||
val layers: List<Layer>
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
var tmp_layers = listOf<Layer>()
|
layers.mapIndexed { index, layer -> layer.position = index }
|
||||||
|
for (i in 0..layers.size-2) {
|
||||||
tmp_layers += Layer(input_n, 0)
|
|
||||||
|
|
||||||
for (layer_n in hidden_n) {
|
|
||||||
for (layer in 0 until layer_n) {
|
|
||||||
tmp_layers += Layer(layer, layer+1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp_layers += Layer(output_n, tmp_layers.size)
|
|
||||||
tmp_layers.last().nodes = tmp_layers.last().nodes.dropLast(1)
|
|
||||||
|
|
||||||
layers = tmp_layers
|
|
||||||
|
|
||||||
for (i in layers.indices-1) {
|
|
||||||
println(i)
|
println(i)
|
||||||
Weight(layers[i], layers[i+1])
|
Weight(layers[i], layers[i+1])
|
||||||
}
|
}
|
||||||
this.count()
|
this.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun count() {
|
private fun count() { for (layer in layers) { layer.count() } }
|
||||||
for (layer in layers) { layer.count() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun input(array: Array<Double>) {
|
fun input(array: Array<Double>) {
|
||||||
for (index in 0 until layers[0].nodes.dropLast(1).size) {
|
for (index in 0 until layers[0].nodes.dropLast(1).size) {
|
||||||
layers[0].nodes[index].value = array[index]
|
layers[0].nodes[index].valuE = array[index]
|
||||||
}
|
}
|
||||||
this.count()
|
this.count()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun back_propo(input: Array<Double>) {
|
private fun backPropagation(input: Array<Double>) {
|
||||||
for (i in input.indices) { layers.last().nodes[i].error = input[i] - layers.last().nodes[i].value }
|
input.mapIndexed { i, v -> layers.last().nodes[i].error = v - layers.last().nodes[i].valuE }
|
||||||
for (layer in layers.dropLast(1).reversed()) {
|
for (layer in layers.drop(1).dropLast(1).reversed()) {
|
||||||
for (node in layer.nodes) {
|
for (node in layer.nodes) {
|
||||||
node.error = 0.toDouble()
|
node.error = 0.toDouble()
|
||||||
for (n_node in node.next_nodes) {
|
for (n_node in node.nextNodes) {
|
||||||
node.error += n_node.error * layer.next_weight!!.weight[listOf(node, n_node)]!!
|
node.error += n_node.error * layer.nextWeight!!.weight[listOf(node, n_node)]!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (layer in layers.dropLast(1)) {
|
for (layer in layers.dropLast(1)) {
|
||||||
for (node in layer.nodes) {
|
for (node in layer.nodes) {
|
||||||
for (n_node in node.next_nodes) {
|
for (n_node in node.nextNodes) {
|
||||||
node.parent.next_weight!!.weight[listOf(node, n_node)] =
|
node.parent.nextWeight!!.weight[listOf(node, n_node)] =
|
||||||
node.parent.next_weight!!.weight[listOf(node, n_node)]!! +
|
node.parent.nextWeight!!.weight[listOf(node, n_node)]!! +
|
||||||
k * n_node.error * activation_fun.logistic_(n_node.value)*node.value
|
k * n_node.error * ActivationFun.logisticDerivative(n_node.valuE)*node.valuE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun teach(sets: Array<Array<Array<Double>>>, epochs: Int = 100000) {
|
fun teach(sets: Array<Array<Array<Double>>>, epochs: Int = 100000, silent: Boolean = true) {
|
||||||
for (epoch in 1..epochs) {
|
for (epoch in 1..epochs) {
|
||||||
println("epoch #$epoch")
|
if (!silent) println("epoch #$epoch")
|
||||||
for (set in sets) {
|
for (set in sets) {
|
||||||
this.input(set[0])
|
this.input(set[0])
|
||||||
this.back_propo(set[1])
|
this.backPropagation(set[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun output(): List<Double> {
|
fun output(): List<Double> {
|
||||||
var output = listOf<Double>()
|
var output = listOf<Double>()
|
||||||
for (node in layers.last().nodes) { output += node.value }
|
for (node in layers.last().nodes) { output += node.valuE }
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class Node(val parent: Layer, val position: Int) {
|
open class Node(val parent: Layer, private val position: Int) {
|
||||||
open var value = 0.toDouble()
|
open var valuE = 0.toDouble()
|
||||||
var error = 0.toDouble()
|
var error = 0.toDouble()
|
||||||
// var tmp = 0.toDouble()
|
var prevNodes = listOf<Node>()
|
||||||
var prev_nodes = listOf<Node>()
|
var nextNodes = listOf<Node>()
|
||||||
var next_nodes = listOf<Node>()
|
|
||||||
|
|
||||||
open fun get_value(): Double {
|
open fun getValue(): Double {
|
||||||
return if (prev_nodes.isEmpty()) value
|
return if (prevNodes.isEmpty()) valuE
|
||||||
else {
|
else {
|
||||||
value = 0.toDouble()
|
valuE = 0.toDouble()
|
||||||
for (node in prev_nodes) {
|
for (node in prevNodes) {
|
||||||
value += node.value * parent.prev_weight!!.weight[listOf(node, this)]!!
|
valuE += node.valuE * parent.prevWeight!!.weight[listOf(node, this)]!!
|
||||||
}
|
}
|
||||||
// tmp = value
|
// tmp = value
|
||||||
value = activation_fun.logistic(value)
|
valuE = ActivationFun.logistic(valuE)
|
||||||
value
|
valuE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "[${parent.position}:${position} | $value ]"
|
return "[${parent.position}:${position} | $valuE ]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Bias(parent: Layer, position: Int) : Node(parent, position) {
|
class Bias(parent: Layer, position: Int) : Node(parent, position) {
|
||||||
override var value = 1.toDouble()
|
override var valuE = 1.toDouble()
|
||||||
override fun get_value() = 1.toDouble()
|
override fun getValue() = 1.toDouble()
|
||||||
}
|
}
|
||||||
|
|
||||||
class Layer(amount: Int, val position: Int) {
|
class Layer(amount: Int, bias: Boolean = true) {
|
||||||
|
var position by Delegates.notNull<Int>()
|
||||||
var nodes = listOf<Node>()
|
var nodes = listOf<Node>()
|
||||||
var next_weight: Weight? = null
|
var nextWeight: Weight? = null
|
||||||
var prev_weight: Weight? = null
|
var prevWeight: Weight? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
for (i in 0 until amount) {
|
for (i in 0 until amount) {
|
||||||
nodes += Node(this, i)
|
nodes += Node(this, i)
|
||||||
}
|
}
|
||||||
nodes += Bias(this, nodes.size)
|
if (bias) nodes += Bias(this, nodes.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun count() {
|
fun count() {
|
||||||
for (node in nodes) { node.get_value() }
|
for (node in nodes) { node.getValue() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,15 +110,15 @@ class Weight(prev_: Layer, next_: Layer) {
|
|||||||
var weight = HashMap<List<Node>, Double>()
|
var weight = HashMap<List<Node>, Double>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
prev_.next_weight = this
|
prev_.nextWeight = this
|
||||||
next_.prev_weight = this
|
next_.prevWeight = this
|
||||||
|
|
||||||
for (input_node in prev_.nodes) {
|
for (input_node in prev_.nodes) {
|
||||||
for (output_node in next_.nodes) {
|
for (output_node in next_.nodes) {
|
||||||
if (output_node is Bias) continue
|
if (output_node is Bias) continue
|
||||||
weight[listOf(input_node, output_node)] = Math.random()
|
weight[listOf(input_node, output_node)] = Math.random()
|
||||||
input_node.next_nodes += output_node
|
input_node.nextNodes += output_node
|
||||||
output_node.prev_nodes += input_node
|
output_node.prevNodes += input_node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,13 +126,9 @@ class Weight(prev_: Layer, next_: Layer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class activation_fun {
|
class ActivationFun {
|
||||||
companion object{
|
companion object{
|
||||||
fun logistic(x: Double) = 1/(1 + Math.E.pow(-x))
|
fun logistic(x: Double) = 1/(1 + Math.E.pow(-x))
|
||||||
fun logistic_(x: Double) = x * (1 - x)
|
fun logisticDerivative(x: Double) = x * (1 - x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Functions {
|
|
||||||
Logistic
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user