PHP . SU
Программирование на PHP, MySQL и другие веб-технологии
Без описания
Поиск в теме | Версия для печати
DlTA
Отправлено: 16 Июня, 2020 - 13:28:56
Постоянный участник
Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010
Помог: 53 раз(а)
Сложил свой код для обработки
Генерирует веса, решает задачу XOR
Спойлер (Отобразить )
PHP:
скопировать код в буфер обмена
function f( $s ) {
}
function df( $s ) {
$val = f( $s ) ;
return $val * ( 1- $val ) ;
}
function w( $ns ) {
$w = [ ] ;
//строим веса
foreach ( $ns as $u => $ct ) {
if ( $u == 0) {
continue ;
}
for ( $kt = 1 ; $kt <= $ct ; $kt ++ ) {
for ( $kf = 0 ; $kf <= $ns [ $u - 1] ; $kf ++ ) {
$w [ $u ] [ $kt ] [ $kf ] =
$w [ $u ] [ $kt ] [ $kf ] == 0
?0. 1
: $w [ $u ] [ $kt ] [ $kf ] ;
}
}
}
return $w ;
}
function p( $v ) {
return str_pad ( $v , 6 , ' ' , STR_PAD_RIGHT
) ; }
function i( & $xy , & $w , & $s , & $i ) {
//$s=[];
//$i=[];
$i = [ ] ;
$i [ 0] = $xy [ 'x' ] ;
foreach ( $i [ 0] as $ki => $vi ) {
$i [ 0] [ $ki ] = f( $i [ 0] [ $ki ] ) ;
}
$s = [ ] ;
echo "\n " ;
foreach ( $w as $u => $lt ) {
if ( ! isset ( $i [ $u - 1
] [ 0
] ) ) { $i [ $u - 1] [ 0] = 1 ;
}
foreach ( $lt as $kt => $lf ) {
//echo "[$u,$kt]";
foreach ( $lf as $kf => $vw ) {
if ( ! isset ( $s [ $u ] [ $kt ] ) ) { $s [ $u ] [ $kt ] = 0 ;
}
//echo "w[$u][$kt][$kf]*i[".($u-1)."][$kf] = ";
//echo ($w[$u][$kt][$kf]*$i[$u-1][$kf])."\n";
$s [ $u ] [ $kt ] +=
$w [ $u ] [ $kt ] [ $kf ] * $i [ $u - 1] [ $kf ] ;
echo "w[$u ][$kt ][$kf ]*i[" . ( $u - 1 ) . ",$kf ] = "
. p( $w [ $u ] [ $kt ] [ $kf ] ) . '* ' . p( $i [ $u - 1] [ $kf ] ) . '= ' ;
echo p( $w [ $u ] [ $kt ] [ $kf ] * $i [ $u - 1] [ $kf ] ) . "\n " ;
//echo $s[$u][$kt]."\n";
}
//echo "\n";
$i [ $u ] [ $kt ] = f( $s [ $u ] [ $kt ] ) ;
//echo "s=".$s[$u][$kt].' ';
echo "s[$u ][$kt ]=" . p( $s [ $u ] [ $kt ] )
. ' ' ;
echo "i[$u ][$kt ]=" . p( $i [ $u ] [ $kt ] )
. "\n " ;
}
}
//print_r(['$y'=>$xy['y'][1], '$i'=>$i[$ur][1]]);
$ur = array_key_last( $i ) ;
echo '[' . implode ( ', ' , $xy [ 'x' ] ) . '] $y=' . $xy [ 'y' ] [ 1 ] . ' $i=' . $i [ $ur ] [ 1 ] . "\n " ;
//print_r(['$i'=>$i, '$w'=>$w]);
}
$step = 20000 ;
$a = $da = 0.5 ;
/*
$data=[
['x'=>[1, 50, 50], 'y'=>[1=>1 ]]
, ['x'=>[1, 20, 20], 'y'=>[1=>1 ]]
, ['x'=>[1, 50, 20], 'y'=>[1=>0 ]]
, ['x'=>[1, 20, 50], 'y'=>[1=>0 ]]
//, ['x'=>[1=> -30], 'y'=>[1=>0 ]]
//, ['x'=>[1=>10], 'y'=>[1=>0]]
//, ['x'=>[1=>30], 'y'=>[1=>0]]
];
*/
$data = [
[ 'x' => [ 1 =>- 1 , 1 ] , 'y' => [ 1 => 1 ] ]
, [ 'x' => [ 1 => 1 , 0 ] , 'y' => [ 1 => 1 ] ]
, [ 'x' => [ 1 => 0 , 0 ] , 'y' => [ 1 => 0 ] ]
, [ 'x' => [ 1 => 1 , 1 ] , 'y' => [ 1=> 0 ] ]
] ;
$s = [ ] ;
$e = [ ] ;
/*
$w=array (
1 =>
array (
1 =>
array (
// 0 => 0.07,
1 => -0.02,
2 => -0.01,
),
2 =>
array (
// 0 => 0.02,
1 => -0.05,
2 => 0.05,
),
3 =>
array (
//0 => -0.09,
1 => 0.07,
2 => -0.07,
),
),
2 =>
array (
1 =>
array (
//0 => 0.03,
1 => 0.07,
2 => -0.06,
3 => 0.1,
),
2 =>
array (
// 0 => -0.01,
1 => -0.01,
2 => 0.04,
3 => -0.04,
),
3 =>
array (
// 0 => 0.03,
1 => -0.04,
2 => 0.05,
3 => -0.01,
),
),
3 =>
array (
1 =>
array (
// 0 => -0.1,
1 => -0.01,
2 => -0.09,
3 => 0.02,
),
),
);
*/
$w = w( [ 2, 2, 2, 1] ) ;
/*
print_r(var_export($w,1));
exit;
*/
$sw = 0 ;
for ( $k = 0 ; $k < $step ; $k ++ ) {
$mse = 0 ;
echo "\n \n $k \n " ;
foreach ( $data as $xy ) {
$i = [ ] ;
$i [ 0] = $xy [ 'x' ] ;
$s = [ ] ;
// нейрон
i( $xy , $w , $s , $i ) ;
//echo $it;
//ksort($i[0]);
echo "\n " . ' i=[' . implode ( ',' , $i [ 0 ] ) . "] \n y={$xy['y']['1']} \n " ;
//print_r(['$y'=>$xy['y'][1], '$i'=>$i]);
$ur = array_key_last( $i ) ;
//echo '$ur='.$ur."\n";
$e = [ ] ;
$se = 0 ;
$ske = 0 ;
// ошибка
$e [ $ur ] [ 1] =
$xy [ 'y' ] [ 1] - $i [ $ur ] [ 1] ;
//$se+=pow(($e[$ur][$ki]),2);
//$ske++;
echo ' i=' . $i [ $ur ] [ 1 ] . "\n " ;
echo " e[$ur ][1]=" . $e [ $ur ] [ 1 ] . "\n " ;
//пересчет ошибок
for ( $u = $ur ; $u > 1 ; $u -- ) {
foreach ( $w [ $u ] as $kt => $lf ) {
if ( $kt == 0) {
continue ;
}
foreach ( $w [ $u ] [ $kt ] as $kf => $vw ) {
if ( ! isset ( $e [ $u - 1
] [ $kf ] ) ) { $e [ $u - 1] [ $kf ] = 0 ;
}
$e [ $u - 1] [ $kf ] +=
$w [ $u ] [ $kt ] [ $kf ] * $e [ $u ] [ $kt ] ;
}
}
}
$mse += pow ( $e [ $ur ] [ 1
] , 2
) ; // пересчет весов
for ( $u = $ur ; $u >= 1 ; $u -- ) {
//print_r(['$e'=>$e, '$u'=>$u]);
//echo " $u\n";
foreach ( $w [ $u ] as $kt => $lt ) {
//print_r(['$lt'=>$lt]);
//нейрон
//echo "$kt\n";
//rsort($i[$u-1]);
/*
$i[$u-1] = array_map(function($val){
return substr($val, 0, 6);
}, $i[$u-1]);*/
echo " $u $kt i["
. substr ( $e [ $u ] [ $kt ] , 0 , 6 ) . "\n " ;
//сумма весов к нейрону
foreach ( $lt as $kf => $vw ) {
$dw = (
$a
* df( $s [ $u ] [ $kt ] )
* $e [ $u ] [ $kt ]
* $i [ $u - 1] [ $kf ]
) ;
echo "dw[$u ,$kt ]=\n " ;
echo ' $a=' . p( $a ) . "\n " ;
echo ' df=' . p( df( $s [ $u ] [ $kt ] ) ) . "\n " ;
echo ' e=' . p( $e [ $u ] [ $kt ] ) . "\n " ;
echo ' i=' . p( $i [ $u - 1] [ $kf ] ) . "\n " ;
echo " =$dw \n " ;
$w [ $u ] [ $kt ] [ $kf ] += $dw ;
/*1
//* df($s[$u][$kt])
* (
$e[$u][$kt] / $sw
//* abs($w[$u][$kt][$kf])
* $w[$u][$kt][$kf]
)
//* $i[$u-1][$kf]
* $a
;
echo "1*({$e[$u][$kt]}/$sw*"
//.abs($w[$u][$kt][$kf])
.$w[$u][$kt][$kf]
.")*$a \n";
echo "dw=".(1
//* df($s[$u][$kt])
* (
$e[$u][$kt] / $sw
//* abs($w[$u][$kt][$kf])
* $w[$u][$kt][$kf]
)
//* $i[$u-1][$kf]
* $a)."\n";
*/
echo " $kf dw=" . str_pad ( $dw , 20 , " " ) ;
echo " w={$w [$u ][$kt ][$kf ]} \n " ;
/*
if ($w[$u][$kt][$kf]==NAN){
exit;
}
*/
}
//print_r(['$w'=>$w]);
}
}
//echo $et;
echo "re \n " ;
i( $xy , $w , $s , $i ) ;
echo "er\n " ;
//echo $it2;
}
//$mse=pow($mse, 0.5);
echo " == mse=$mse \n \n " ;
}
echo "-----\n " ;
for ( $k = 0 ; $k < 1 ; $k ++ ) {
// гручим результат
foreach ( $data as $xy ) {
$i = [ ] ;
$i [ 0] = $xy [ 'x' ] ;
foreach ( $i [ 0] as $ki => $vi ) {
//$i[0][$ki] = f($i[0][$ki]);
}
$s = [ ] ;
i( $xy , $w , $s , $i ) ;
//echo $it;
echo ' $y=' . $xy [ 'y' ] [ 1 ] . ' $i=' . $i [ $ur ] [ 1 ] . "\n " ;
}
}
Может кому-то будет интересно
Скрипт писался по консоль на телефоне.
Иногда задача не сходится, большая ошибка, повторители попытку
Обычно XOR считается за 2.5-5 тысяч.
А иногда только на 15 тысячах ошибка опускается к проценту.
Есть вывод в изображение. Но в другом файле.
По коду: коменты в коде есть.
DlTA
Отправлено: 20 Июня, 2020 - 13:03:55
Постоянный участник
Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010
Помог: 53 раз(а)
Спойлер (Отобразить )
PHP:
скопировать код в буфер обмена
<?PHP
//include('f.php');
function f( $s ) {
}
function df( $s ) {
$val = f( $s ) ;
return $val * ( 1- $val ) ;
}
function w( $ns ) {
$w = [ ] ;
//строим веса
foreach ( $ns as $u => $ct ) {
if ( $u == 0) {
continue ;
}
for ( $kt = 1 ; $kt <= $ct ; $kt ++ ) {
for ( $kf = 0 ; $kf <= $ns [ $u - 1] ; $kf ++ ) {
$w [ $u ] [ $kt ] [ $kf ] =
$w [ $u ] [ $kt ] [ $kf ] == 0
?0. 1
: $w [ $u ] [ $kt ] [ $kf ] ;
}
}
}
return $w ;
}
function p( $v ) {
}
function i( & $xy , & $w , & $s , & $i ) {
$i = [ ] ;
$i [ 0] = $xy [ 'x' ] ;
foreach ( $i [ 0] as $ki => $vi ) {
$i [ 0] [ $ki ] = f( $i [ 0] [ $ki ] ) ;
}
$s = [ ] ;
foreach ( $w as $u => $lt ) {
if ( ! isset ( $i [ $u - 1
] [ 0
] ) ) { $i [ $u - 1] [ 0] = 1 ;
}
foreach ( $lt as $kt => $lf ) {
//echo "[$u,$kt]";
foreach ( $lf as $kf => $vw ) {
if ( ! isset ( $s [ $u ] [ $kt ] ) ) { $s [ $u ] [ $kt ] = 0 ;
}
$s [ $u ] [ $kt ] +=
$w [ $u ] [ $kt ] [ $kf ] * $i [ $u - 1] [ $kf ] ;
}
//echo "\n";
$i [ $u ] [ $kt ] = f( $s [ $u ] [ $kt ] ) ;
}
}
$ur = array_key_last( $i ) ;
}
$step = 1000 ;
$a = 1.0 ;
// генерить картинки
$vdi = 0 ;
$data = [
[ 'x' => [ 1 => 0 , 1 ] , 'y' => [ 1 => 1 , 1 , 0 ] ]
, [ 'x' => [ 1 => 1 , 0 ] , 'y' => [ 1 => 1 , 1 , 0 ] ]
, [ 'x' => [ 1 => 0 , 0 ] , 'y' => [ 1 => 0 , 0 , 0 ] ]
, [ 'x' => [ 1 => 1 , 1 ] , 'y' => [ 1 => 0, 1, 1] ]
] ;
$s = [ ] ;
$e = [ ] ;
$w = w( [ 2, 3, 3, 3] ) ;
$sw = 0 ;
for ( $k = 0 ; $k < $step ; $k ++ ) {
$mse = 0 ;
echo "\r $k " ;
foreach ( $data as $xy ) {
$i = [ ] ;
$i [ 0] = $xy [ 'x' ] ;
$s = [ ] ;
// нейрон
i( $xy , $w , $s , $i ) ;
//print_r(['$y'=>$xy['y'][1], '$i'=>$i]);
$ur = array_key_last( $i ) ;
//echo '$ur='.$ur."\n";
$e = [ ] ;
$se = 0 ;
$ske = 0 ;
// ошибка
foreach ( $xy [ 'y' ] as $idy => $yv ) {
// $yv
$e [ $ur ] [ $idy ] =
$xy [ 'y' ] [ $idy ] - $i [ $ur ] [ $idy ] ;
}
//пересчет ошибок
for ( $u = $ur ; $u > 1 ; $u -- ) {
foreach ( $w [ $u ] as $kt => $lf ) {
if ( $kt == 0) {
continue ;
}
foreach ( $w [ $u ] [ $kt ] as $kf => $vw ) {
if ( ! isset ( $e [ $u - 1
] [ $kf ] ) ) { $e [ $u - 1] [ $kf ] = 0 ;
}
$e [ $u - 1] [ $kf ] +=
$w [ $u ] [ $kt ] [ $kf ] * $e [ $u ] [ $kt ] ;
}
}
}
//$mse+=pow($e[$ur][1], 2);
foreach ( $e [ $ur ] as $ee ) {
}
// пересчет весов
for ( $u = $ur ; $u >= 1 ; $u -- ) {
foreach ( $w [ $u ] as $kt => $lt ) {
//сумма весов к нейрону
foreach ( $lt as $kf => $vw ) {
$dw = (
$a
* df( $s [ $u ] [ $kt ] )
* $e [ $u ] [ $kt ]
* $i [ $u - 1] [ $kf ]
) ;
$w [ $u ] [ $kt ] [ $kf ] += $dw ;
}
}
}
// пересчет нейрона после обучения
i( $xy , $w , $s , $i ) ;
}
echo " == mse=$mse " ;
// генерим картинку
if ( $vdi == 1 and $k % 10 == 0 ) {
//$k = $k/10;
$n = str_pad ( $k , 6 , '0' , STR_PAD_LEFT
) ; `php - f tv. php $n `;
}
// при большой ошибке очимся дольше
if ( $k >= ( $step - 1)
and $mse > 0. 01
and $step < 20000
) {
$step += 200 ;
// скорость обучения
$a *= 0.99 ;
}
}
echo "-----\n " ;
//print_r([$w]);
// гручим результат
foreach ( $data as $xy ) {
$i = [ ] ;
$i [ 0] = $xy [ 'x' ] ;
foreach ( $i [ 0] as $ki => $vi ) {
$i [ 0] [ $ki ] = f( $i [ 0] [ $ki ] ) ;
}
$s = [ ] ;
i( $xy , $w , $s , $i ) ;
foreach ( $i [ $ur ] as $ik => $iv ) {
echo " y[$ik ]=" . $xy [ 'y' ] [ $ik ]
. " i[$ik ]=" . $i [ $ur ] [ $ik ] . "\n " ;
}
}
if ( $mse > 0. 1) {
}
echo "\n mse=$mse \n " ;
Продолжение:
На входе x, y, а на выходе x xor y, x or y, x and y
1/5 не сходятся, нежно повторить пересчёт.
Добавил добавление количество эпох при большой ошибке MSE, но редко что то даёт.
DlTA
Отправлено: 20 Июня, 2020 - 22:28:26
Постоянный участник
Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010
Помог: 53 раз(а)
для повышения качества работы сети можно поднять количество нейронов первого слоя
$w = w([2, 3 , 3, 3]);
на
$w = w([2, 4 , 3, 3]);
КПД обучения поднимается до 90%(+-)
Но если поднять количество слоем нейронов или количество нейроном на последнем слое
$w = w([2, 4, 3 , 3]); или
$w = w([2, 4, 3, 3, 3 , 3]); то результат будет печальный))
(Отредактировано автором: 20 Июня, 2020 - 22:32:09)
DlTA
Отправлено: 08 Июля, 2020 - 12:40:25
Постоянный участник
Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010
Помог: 53 раз(а)
Маленький код
Спойлер (Отобразить )
PHP:
скопировать код в буфер обмена
<?PHP
include ( 'f2.php' ) ;
$w = w( [ 2, 2, 1] ) ;
$data = [
[ 'x' => [ 1 => 1 , 1 ] , 'y' => [ 1 => 1 ] ]
, [ 'x' => [ 1 => 0 , 0 ] , 'y' => [ 1=> 0] ]
] ;
$i = [ ] ; $s = [ ] ; $e = [ ] ;
do {
foreach ( $data as $xy ) {
i( $xy , $w , $s , $i ) ;
$ur = array_key_last( $i ) ;
$e = [ ] ;
e( $w , $e , $i , $xy [ 'y' ] , $ur ) ;
//print_r($e);
rw( $w , $i , $s , $e , $ur , $a ) ;
foreach ( $e [ $ur ] as $ev ) {
//print_r([$ev]);
mse_step:: add_e ( $ev ) ;
}
}
echo "\r " . mse_step:: get_c ( ) . ' ' . mse_step:: get_old_mse ( ) ;
} while ( mse_step:: ns ( ) != 0) ;
echo "\n " . mse_step:: get_c ( ) . ' ' . mse_step:: get_old_mse ( ) . "\n " ;
и внутренности
Спойлер (Отобразить )
f2.php
PHP:
скопировать код в буфер обмена
<?PHP
//include('f2.php');
class mse_step {
static private
$s = 0
, $sme = 0
, $old_mse = 0
, $step = 10
, $c = 0
, $max = 10000
, $min = 50
, $as = 30
, $lim_mse = 0.004 ;
static public function add_e( $e ) {
self :: $s ++;
}
static private function mse( ) {
if ( self :: $s == 0) return 0 ;
return self :: $sme / self :: $s ;
}
static public function get_mse_clear( ) {
self :: $old_mse = self :: mse ( ) ;
self :: $sme = 0 ;
self :: $s = 0 ;
return self :: $old_mse ;
}
static public function get_old_mse( ) {
return self :: $old_mse ;
}
static public function get_c( ) {
return self :: $c ;
}
/**
* продолжить обучение 1, завершить 0
* @return int 1,0
*/
static public function ns( ) {
if ( self :: $c > self :: $max ) {
return 0 ;
}
elseif ( self :: get_mse_clear ( ) < self :: $lim_mse ) {
return 0 ;
}
elseif ( self :: $c < self :: $min ) {
self :: $c ++;
return 1 ;
}
else {
self :: $c ++;
return 1 ;
}
}
}
function f( $s ) {
}
function df( $s ) {
$val = f( $s ) ;
return $val * ( 1- $val ) ;
}
function w( $ns ) {
$w = [ ] ;
//строим веса
foreach ( $ns as $u => $ct ) {
if ( $u == 0) {
continue ;
}
for ( $kt = 1 ; $kt <= $ct ; $kt ++ ) {
for ( $kf = 0 ; $kf <= $ns [ $u - 1] ; $kf ++ ) {
$w [ $u ] [ $kt ] [ $kf ] =
$w [ $u ] [ $kt ] [ $kf ] == 0
?0. 1
: $w [ $u ] [ $kt ] [ $kf ] ;
}
}
}
return $w ;
}
function p( $v ) {
}
function i( & $xy , & $w , & $s , & $i ) {
$i = [ ] ;
$i [ 0] = $xy [ 'x' ] ;
foreach ( $i [ 0] as $ki => $vi ) {
$i [ 0] [ $ki ] = f( $i [ 0] [ $ki ] ) ;
}
$s = [ ] ;
foreach ( $w as $u => $lt ) {
if ( ! isset ( $i [ $u - 1
] [ 0
] ) ) { $i [ $u - 1] [ 0] = 1 ;
}
foreach ( $lt as $kt => $lf ) {
//echo "[$u,$kt]";
foreach ( $lf as $kf => $vw ) {
if ( ! isset ( $s [ $u ] [ $kt ] ) ) { $s [ $u ] [ $kt ] = 0 ;
}
$s [ $u ] [ $kt ] +=
$w [ $u ] [ $kt ] [ $kf ] * $i [ $u - 1] [ $kf ] ;
}
//echo "\n";
$i [ $u ] [ $kt ] = f( $s [ $u ] [ $kt ] ) ;
}
}
$ur = array_key_last( $i ) ;
}
function rw( & $w , & $i , & $s , & $e , $ur , & $a = 1 ) {
// пересчет весов
for ( $u = $ur ; $u >= 1 ; $u -- ) {
$a = ra( $i [ $u - 1] ) ;
//print_r($a);
//exit;
foreach ( $w [ $u ] as $kt => $lt ) {
//сумма весов к нейрону
foreach ( $lt as $kf => $vw ) {
$dw = (
$a
* df( $s [ $u ] [ $kt ] )
* $e [ $u ] [ $kt ]
* $i [ $u - 1] [ $kf ]
) ;
$w [ $u ] [ $kt ] [ $kf ] += $dw ;
}
}
}
}
/**
* расчет ошибки по данным
*
*/
function ra( $ld ) {
$s = 0 ;
foreach ( $ld as $d ) {
}
return 1/ ( 1+ $s ) ;
}
function e( $w , & $e , $i , $y , $ur ) {
// ошибка
foreach ( $y as $idy => $yv ) {
// $yv
$e [ $ur ] [ $idy ] =
$yv - $i [ $ur ] [ $idy ] ;
}
//пересчет ошибок
for ( $u = $ur ; $u > 1 ; $u -- ) {
foreach ( $w [ $u ] as $kt => $lf ) {
if ( $kt == 0) {
continue ;
}
foreach ( $w [ $u ] [ $kt ] as $kf => $vw ) {
if ( ! isset ( $e [ $u - 1
] [ $kf ] ) ) { $e [ $u - 1] [ $kf ] = 0 ;
}
$e [ $u - 1] [ $kf ] +=
$w [ $u ] [ $kt ] [ $kf ] * $e [ $u ] [ $kt ] ;
}
}
}
}
Поиск в теме | Версия для печати
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Вопросы новичков »
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
Powered by ExBB FM 1.0 RC1. InvisionExBB