人工智能学习之路

多层神经网络,从零开始——(二)、Fortran随机生成“双月”

2018-06-22  本文已影响0人  忆霜晨

“双月”分类问题(The double-moon classification problem)[1]是一个简单的非线性分类问题,可以用于初步测试程序。数据的示意图如下,半径 r = 10,带宽 w = 6,距离 d < 0 时,这是一个非线性分类问题。

使用Fortran代码生成该数据示意图如下(d = -4)。

PROGRAM MAIN
use mod_DoubleMoonDataGen
implicit none
    integer :: data_count = 3000
    real(PRECISION) :: distance = -4.0

    call double_moon_data_gen(distance, data_count)
    
    
END PROGRAM
module mod_DoubleMoonDataGen
    
    integer, parameter :: SINGLE = 4
    integer, parameter :: DOUBLE = 8
    integer, parameter :: PRECISION = DOUBLE
    
    real(PRECISION), parameter :: radius = 10
    real(PRECISION), parameter :: width = 6
    real(PRECISION), save, private :: distance
    integer, save, private :: data_count
    
    !* (1,j): x, (2,j): y
    integer, dimension(:), allocatable :: random_label_data
    real(PRECISION), dimension(:,:), allocatable :: random_double_moon_data
    real(PRECISION), dimension(:,:), allocatable :: double_moon_data_top
    real(PRECISION), dimension(:,:), allocatable :: double_moon_data_bottom
    
contains
    
    subroutine double_moon_data_gen( dis, count )    
    implicit none
        real(PRECISION), intent(in) :: dis
        integer, intent(in) :: count
    
        integer :: top_count, bottom_count
        integer :: j
        real(PRECISION) :: random_label, random_angle, random_r
        real(PRECISION) :: random_x, random_y
        real(PRECISION) :: PI
        
        distance = dis
        data_count = count
        PI = 4.0 * ATAN(1.0)

        allocate(random_double_moon_data(2, count))
        allocate(random_label_data(count))
              
        call RANDOM_SEED()
        
        top_count = 0
        bottom_count = 0
        do j=1, count
            call RANDOM_NUMBER(random_label)
            
            if (random_label > 0.5) then
                random_label_data(j) = 1
                top_count = top_count + 1
                
                call RANDOM_NUMBER(random_angle)
                call RANDOM_NUMBER(random_r)
                
                random_angle = PI * random_angle
                random_r = width * random_r + &
                    (radius - 0.5*width)
                
                random_double_moon_data(1, j) = &
                    random_r * COS(random_angle)
                random_double_moon_data(2, j) = &
                    random_r * SIN(random_angle)
            else
                random_label_data(j) = -1
                bottom_count = bottom_count + 1
                
                call RANDOM_NUMBER(random_angle)
                call RANDOM_NUMBER(random_r)
                
                random_angle = -PI * random_angle
                random_r = width * random_r + &
                    (radius - 0.5*width)
                
                random_double_moon_data(1, j) = &
                    random_r * COS(random_angle) + radius
                random_double_moon_data(2, j) = &
                    random_r * SIN(random_angle) - distance
            end if            
        end do      
        
        allocate(double_moon_data_top(2, top_count))
        allocate(double_moon_data_bottom(2, bottom_count))
        
        top_count = 1
        bottom_count = 1
        do j=1, count
            if (random_label_data(j) == 1) then
                double_moon_data_top(:, top_count) = &
                    random_double_moon_data(:, j)
                top_count = top_count + 1
            else
                double_moon_data_bottom(:, bottom_count) = &
                    random_double_moon_data(:, j)
                bottom_count = bottom_count + 1
            end if
        end do
        
        call output_data('random_double_moon_data.dat', &
            random_double_moon_data, random_label_data)
        
        call output_data('top_double_moon_data.plt', &
            double_moon_data_top)
        
        call output_data('bottom_double_moon_data.plt', &
            double_moon_data_bottom)
        
        return
    end subroutine
    
    
    subroutine output_data( file_name, array, label )
    implicit none
        character(len=*), intent(in) :: file_name
        real(PRECISION), dimension(:,:), intent(in) :: array
        integer, dimension(:), optional, intent(in) :: label 
        
        integer :: array_shape(2)
        integer :: j
        
        array_shape = SHAPE(array)
        
        open(unit=33, file=file_name, form='formatted', status='replace')
        
        if (PRESENT(label)) then
            do j=1, array_shape(2)
                write(33, *) array(1, j), array(2, j), label(j)
            end do
        else
            do j=1, array_shape(2)
                write(33, *) array(1, j), array(2, j)
            end do
        end if
        
        close(33)
    
        return
    end subroutine
    
end module

附录

多层神经网络,从零开始——(一)、Fortran读取MNIST数据集
多层神经网络,从零开始——(二)、Fortran随机生成“双月”分类问题数据
多层神经网络,从零开始——(三)、BP神经网络公式的详细推导
多层神经网络,从零开始——(四)、多层BP神经网络的矩阵形式
多层神经网络,从零开始——(五)、定义数据结构
多层神经网络,从零开始——(六)、激活函数
多层神经网络,从零开始——(七)、损失函数
多层神经网络,从零开始——(八)、分类问题中为什么使用交叉熵作为损失函数
多层神经网络,从零开始——(九)、优化函数
多层神经网络,从零开始——(十)、参数初始化
多层神经网络,从零开始——(十一)、实现训练类
多层神经网络,从零开始——(十二)、实现算例类
多层神经网络,从零开始——(十三)、关于并行计算的简单探讨


  1. Simon Haykin. Neural Networks and Learning Machines, Third Edition. Pearson Education, 2009. 申富饶, 徐烨, 郑俊等译. 神经网络与机器学习, 第三版. 机械工业出版社, 2011.

上一篇下一篇

猜你喜欢

热点阅读