Archived
1
0

Some corrections

This commit is contained in:
VerySweetBread
2022-11-24 00:15:24 +03:00
parent 1a8cae23b2
commit ca4b9e332c
68 changed files with 93 additions and 78 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
View File
@@ -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.
+47 -13
View File
@@ -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
)
)
}
} }
+45 -65
View File
@@ -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
}