├── .gitignore
├── CMakeLists.txt
├── README.rst
├── cmake
├── findMKL.cmake
└── findThreads.cmake
├── convdata.py
├── convnet.py
├── data.py
├── example-layers
├── layer-params-18pct.cfg
├── layer-params-19pct.cfg
├── layer-params-80sec.cfg
├── layer-params-conv-local-11pct.cfg
├── layer-params-conv-local-13pct.cfg
├── layer-params-example.cfg
├── layer-params.gc.cfg
├── layers-18pct.cfg
├── layers-19pct.cfg
├── layers-80sec.cfg
├── layers-conv-local-11pct.cfg
├── layers-conv-local-13pct.cfg
├── layers-example.cfg
└── layers.gc.cfg
├── gpumodel.py
├── include
├── common
│ ├── matrix.h
│ ├── matrix_funcs.h
│ ├── queue.h
│ └── thread.h
├── convnet.cuh
├── cost.cuh
├── cudaconv2
│ ├── conv_util.cuh
│ └── cudaconv2.cuh
├── data.cuh
├── layer.cuh
├── layer_kernels.cuh
├── neuron.cuh
├── nvmatrix
│ ├── nvmatrix.cuh
│ ├── nvmatrix_kernels.cuh
│ └── nvmatrix_operators.cuh
├── pyconvnet.cuh
├── util.cuh
├── weights.cuh
└── worker.cuh
├── layer.py
├── options.py
├── ordereddict.py
├── shownet.py
├── src
├── common
│ ├── CMakeLists.txt
│ └── matrix.cpp
├── convnet.cu
├── cost.cu
├── cudaconv2
│ ├── CMakeLists.txt
│ ├── conv_util.cu
│ ├── filter_acts.cu
│ ├── img_acts.cu
│ └── weight_acts.cu
├── data.cu
├── layer.cu
├── layer_kernels.cu
├── neuron.cu
├── nvmatrix
│ ├── CMakeLists.txt
│ ├── nvmatrix.cu
│ └── nvmatrix_kernels.cu
├── pyconvnet.cu
├── util.cu
├── weights.cu
└── worker.cu
└── util.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # CMake
2 | CMakeCache.txt
3 | CMakeFiles
4 | Makefile
5 | cmake_install.cmake
6 | install_manifest.txt
7 |
8 | # Byte-compiled / optimized / DLL files
9 | __pycache__/
10 | *.py[cod]
11 |
12 | # C extensions
13 | *.so
14 | *.a
15 |
16 | # Distribution / packaging
17 | .Python
18 | env/
19 | bin/
20 | build/
21 | develop-eggs/
22 | dist/
23 | eggs/
24 | lib/
25 | lib64/
26 | parts/
27 | sdist/
28 | var/
29 | *.egg-info/
30 | .installed.cfg
31 | *.egg
32 |
33 | # Installer logs
34 | pip-log.txt
35 | pip-delete-this-directory.txt
36 |
37 | # Mr Developer
38 | .mr.developer.cfg
39 | .project
40 | .pydevproject
41 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required (VERSION 2.8)
2 | project (cuda-convnet )
3 |
4 | if(MSVC)
5 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
6 | set(THREADS_USE_PTHREADS_WIN32 TRUE)
7 |
8 | # set the place of pthread.h
9 | set(THREADS_PTHREAD_WIN32_INC "C:/cuda-convnet/pthreads-w32-2-9-1-release/Pre-built.2/include")
10 |
11 | # set the place you install mkl (the folder containing "./mkl")
12 | set(MKL_ROOT "C:/Program Files (x86)/Intel/Composer XE 2013")
13 |
14 | string(REGEX REPLACE "/Z[iI7]" ""
15 | CMAKE_CXX_FLAGS_RELEASE
16 | "${CMAKE_CXX_FLAGS_RELEASE}")
17 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Z7")
18 | endif()
19 |
20 | find_package (CUDA REQUIRED)
21 | if(MSVC)
22 | find_package (MKL REQUIRED)
23 | find_package (Threads REQUIRED)
24 | else()
25 | find_package (BLAS REQUIRED)
26 | find_path(BLAS_INCLUDE_DIRS cblas.h
27 | HINTS
28 | "/System/Library/Frameworks/vecLib.framework/Versions/Current/Headers/"
29 | "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Headers/"
30 | )
31 | endif()
32 | find_package (PythonLibs 2.7 REQUIRED)
33 | find_package (PythonInterp 2.7 REQUIRED)
34 |
35 | find_path(CUDA_COMMON_INCLUDE_DIRS
36 | helper_cuda.h
37 | PATHS ${CUDA_SDK_SEARCH_PATH}
38 | "/usr/local/cuda"
39 | "/Developer/NVIDIA/CUDA-6.0"
40 | "C:/ProgramData/NVIDIA Corporation/CUDA Samples/v6.0/common/inc"
41 | PATH_SUFFIXES "samples/common/inc"
42 | DOC "Location of helper_cuda.h"
43 | NO_DEFAULT_PATH
44 | )
45 |
46 | if(APPLE)
47 | LIST(APPEND CUDA_NVCC_FLAGS -ccbin /usr/bin/clang)
48 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++")
49 | SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libstdc++")
50 | endif(APPLE)
51 |
52 | #list(APPEND CUDA_NVCC_FLAGS -gencode arch=compute_20,code=sm_20)
53 | list(APPEND CUDA_NVCC_FLAGS -gencode arch=compute_30,code=sm_30)
54 | #list(APPEND CUDA_NVCC_FLAGS -gencode arch=compute_32,code=sm_32)
55 | #list(APPEND CUDA_NVCC_FLAGS -gencode arch=compute_35,code=sm_35)
56 | #list(APPEND CUDA_NVCC_FLAGS -gencode arch=compute_50,code=sm_50)
57 |
58 | IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
59 | list(APPEND CMAKE_CXX_FLAGS -fPIC)
60 | ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
61 |
62 | execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
63 | "import numpy as n; print(n.get_include());"
64 | RESULT_VARIABLE _NUMPY_SEARCH_SUCCESS
65 | OUTPUT_VARIABLE _NUMPY_VALUES
66 | ERROR_VARIABLE _NUMPY_ERROR_VALUE
67 | OUTPUT_STRIP_TRAILING_WHITESPACE
68 | )
69 | if(_NUMPY_SEARCH_SUCCESS MATCHES 0)
70 | string(REGEX REPLACE ";" "\\\\;" _NUMPY_VALUES ${_NUMPY_VALUES})
71 | string(REGEX REPLACE "\n" ";" _NUMPY_VALUES ${_NUMPY_VALUES})
72 | list(GET _NUMPY_VALUES 0 NUMPY_INCLUDE_DIRS)
73 | string(REGEX REPLACE "\\\\" "/" NUMPY_INCLUDE_DIRS ${NUMPY_INCLUDE_DIRS})
74 | else()
75 | message(FATAL_ERROR "NumPy import failure:\n${_NUMPY_ERROR_VALUE}")
76 | endif()
77 |
78 | if (MSVC)
79 | include_directories (
80 | ${CUDA_INCLUDE_DIRS}
81 | ${CUDA_COMMON_INCLUDE_DIRS}
82 | ${PYTHON_INCLUDE_DIRS}
83 | ${NUMPY_INCLUDE_DIRS}/numpy
84 | ${MKL_INCLUDE_DIR}
85 | ${THREADS_PTHREADS_INCLUDE_DIR}
86 | include/common
87 | include/nvmatrix
88 | include/cudaconv2
89 | include/
90 | )
91 | else()
92 | include_directories (
93 | ${BLAS_INCLUDE_DIRS}
94 | ${CUDA_INCLUDE_DIRS}
95 | ${CUDA_COMMON_INCLUDE_DIRS}
96 | ${PYTHON_INCLUDE_DIRS}
97 | ${NUMPY_INCLUDE_DIRS}/numpy
98 | include/common
99 | include/nvmatrix
100 | include/cudaconv2
101 | include/
102 | )
103 | endif()
104 |
105 | add_subdirectory (src/common)
106 | add_subdirectory (src/nvmatrix)
107 | add_subdirectory (src/cudaconv2)
108 |
109 | CUDA_ADD_LIBRARY (convnet SHARED
110 | src/convnet.cu
111 | src/cost.cu
112 | src/data.cu
113 | src/layer.cu
114 | src/layer_kernels.cu
115 | src/neuron.cu
116 | src/pyconvnet.cu
117 | src/util.cu
118 | src/weights.cu
119 | src/worker.cu
120 | )
121 |
122 | if(MSVC)
123 | set_target_properties (convnet
124 | PROPERTIES
125 | PREFIX "_"
126 | SUFFIX ".pyd"
127 | )
128 | else()
129 | set_target_properties (convnet
130 | PROPERTIES
131 | PREFIX "_"
132 | SUFFIX ".so"
133 | )
134 | endif()
135 |
136 | if(MSVC)
137 | TARGET_LINK_LIBRARIES (convnet
138 | common
139 | nvmatrix
140 | cudaconv2
141 | ${PYTHON_LIBRARIES}
142 | ${CUDA_CUBLAS_LIBRARIES}
143 | ${MKL_LIBRARIES}
144 | ${CMAKE_THREAD_LIBS_INIT}
145 | )
146 | else()
147 | TARGET_LINK_LIBRARIES (convnet
148 | common
149 | nvmatrix
150 | cudaconv2
151 | ${PYTHON_LIBRARIES}
152 | ${BLAS_LIBRARIES}
153 | ${CUDA_CUBLAS_LIBRARIES}
154 | )
155 | endif()
156 |
157 | CUDA_BUILD_CLEAN_TARGET()
158 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | This is my fork of the ``cuda-convnet`` convolutional neural network
2 | implementation written by Alex Krizhevsky.
3 |
4 | ``cuda-convnet`` has quite extensive documentation itself. Find the
5 | `MAIN DOCUMENTATION HERE `_.
6 |
7 | **Update**: A newer version, `cuda-convnet 2
8 | `_, has been released by
9 | Alex. This fork is still based on the original cuda-convnet.
10 |
11 | ===================
12 | Additional features
13 | ===================
14 |
15 | This document will only describe the small differences between
16 | ``cuda-convnet`` as hosted on Google Code and this version.
17 |
18 | Dropout
19 | =======
20 |
21 | Dropout is a relatively new regularization technique for neural
22 | networks. See the `Improving neural networks by preventing
23 | co-adaptation of feature detectors `_
24 | and `Improving Neural Networks with Dropout
25 | `_ papers for
26 | details.
27 |
28 | To set a dropout rate for one of our layers, we use the ``dropout``
29 | parameter in our model's ``layer-params`` configuration file. For
30 | example, we could use dropout for the last layer in the CIFAR example
31 | by modifying the section for the fc10 layer to look like so::
32 |
33 | [fc10]
34 | epsW=0.001
35 | epsB=0.002
36 | # ...
37 | dropout=0.5
38 |
39 | In practice, you'll probably also want to double the number of
40 | ``outputs`` in that layer.
41 |
42 |
43 | CURAND random seeding
44 | =====================
45 |
46 | An environment variable ``CONVNET_RANDOM_SEED``, if set, will be used
47 | to set the CURAND library's random seed. This is important in order
48 | to get reproducable results.
49 |
50 |
51 | Updated to work with CUDA via CMake
52 | ===================================
53 |
54 | The build configuration and code has been updated to work with CUDA
55 | via CMake. Run ``cmake .`` and then ``make``. If you have an alternative
56 | BLAS library just set it with for example ``cmake -DBLAS_LIBRARIES=/usr/lib/libcblas.so .``.
57 |
--------------------------------------------------------------------------------
/cmake/findMKL.cmake:
--------------------------------------------------------------------------------
1 | # - Find the MKL libraries
2 | # Modified from Armadillo's ARMA_FindMKL.cmake
3 | # This module defines
4 | # MKL_INCLUDE_DIR, the directory for the MKL headers
5 | # MKL_LIB_DIR, the directory for the MKL library files
6 | # MKL_COMPILER_LIB_DIR, the directory for the MKL compiler library files
7 | # MKL_LIBRARIES, the libraries needed to use Intel's implementation of BLAS & LAPACK.
8 | # MKL_FOUND, If false, do not try to use MKL; if true, the macro definition USE_MKL is added.
9 |
10 | # Set the include path
11 | # TODO: what if MKL is not installed in /opt/intel/mkl?
12 | # try to find at /opt/intel/mkl
13 | # in windows, try to find MKL at C:/Program Files (x86)/Intel/Composer XE/mkl
14 |
15 | if ( WIN32 )
16 | set(MKLROOT_PATH ${MKL_ROOT} CACHE PATH "Where the MKL are stored")
17 | else ( WIN32 )
18 | set(MKLROOT_PATH "/opt/intel" CACHE PATH "Where the MKL are stored")
19 | endif ( WIN32 )
20 |
21 | if (EXISTS ${MKLROOT_PATH}/mkl)
22 | SET(MKL_FOUND TRUE)
23 | message("MKL is found at ${MKLROOT_PATH}/mkl")
24 | IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
25 | set( USE_MKL_64BIT On )
26 | if ( ARMADILLO_FOUND )
27 | if ( ARMADILLO_BLAS_LONG_LONG )
28 | set( USE_MKL_64BIT_LIB On )
29 | ADD_DEFINITIONS(-DMKL_ILP64)
30 | message("MKL is linked against ILP64 interface ... ")
31 | endif ( ARMADILLO_BLAS_LONG_LONG )
32 | endif ( ARMADILLO_FOUND )
33 | ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
34 | set( USE_MKL_64BIT Off )
35 | ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
36 | else (EXISTS ${MKLROOT_PATH}/mkl)
37 | SET(MKL_FOUND FALSE)
38 | message("MKL is NOT found ... ")
39 | endif (EXISTS ${MKLROOT_PATH}/mkl)
40 |
41 | if (MKL_FOUND)
42 | set(MKL_INCLUDE_DIR "${MKLROOT_PATH}/mkl/include")
43 | ADD_DEFINITIONS(-DUSE_MKL)
44 | if ( USE_MKL_64BIT )
45 | set(MKL_LIB_DIR "${MKLROOT_PATH}/mkl/lib/intel64")
46 | set(MKL_COMPILER_LIB_DIR "${MKLROOT_PATH}/compiler/lib/intel64")
47 | set(MKL_COMPILER_LIB_DIR ${MKL_COMPILER_LIB_DIR} "${MKLROOT_PATH}/lib/intel64")
48 | if ( USE_MKL_64BIT_LIB )
49 | if ( WIN32 )
50 | set(MKL_LIBRARIES ${MKL_LIBRARIES} mkl_intel_ilp64)
51 | else ( WIN32 )
52 | set(MKL_LIBRARIES ${MKL_LIBRARIES} libmkl_intel_ilp64.a)
53 | endif ( WIN32 )
54 | else ( USE_MKL_64BIT_LIB )
55 | if ( WIN32 )
56 | set(MKL_LIBRARIES ${MKL_LIBRARIES} mkl_intel_lp64)
57 | else ( WIN32 )
58 | set(MKL_LIBRARIES ${MKL_LIBRARIES} libmkl_intel_lp64.a)
59 | endif ( WIN32 )
60 | endif ( USE_MKL_64BIT_LIB )
61 | else ( USE_MKL_64BIT )
62 | set(MKL_LIB_DIR "${MKLROOT_PATH}/mkl/lib/ia32")
63 | set(MKL_COMPILER_LIB_DIR "${MKLROOT_PATH}/compiler/lib/ia32")
64 | set(MKL_COMPILER_LIB_DIR ${MKL_COMPILER_LIB_DIR} "${MKLROOT_PATH}/lib/ia32")
65 | if ( WIN32 )
66 | set(MKL_LIBRARIES ${MKL_LIBRARIES} mkl_intel_c)
67 | else ( WIN32 )
68 | set(MKL_LIBRARIES ${MKL_LIBRARIES} libmkl_intel.a)
69 | endif ( WIN32 )
70 | endif ( USE_MKL_64BIT )
71 |
72 | if ( WIN32 )
73 | SET(MKL_LIBRARIES ${MKL_LIBRARIES} mkl_intel_thread)
74 | SET(MKL_LIBRARIES ${MKL_LIBRARIES} mkl_core)
75 | SET(MKL_LIBRARIES ${MKL_LIBRARIES} libiomp5md)
76 | else ( WIN32 )
77 | SET(MKL_LIBRARIES ${MKL_LIBRARIES} libmkl_intel_thread.a)
78 | SET(MKL_LIBRARIES ${MKL_LIBRARIES} libmkl_core.a)
79 | SET(MKL_LIBRARIES ${MKL_LIBRARIES} iomp5)
80 | endif ( WIN32 )
81 | endif (MKL_FOUND)
82 |
83 | IF (MKL_FOUND)
84 | IF (NOT MKL_FIND_QUIETLY)
85 | MESSAGE(STATUS "Found MKL libraries: ${MKL_LIBRARIES}")
86 | MESSAGE(STATUS "MKL_INCLUDE_DIR: ${MKL_INCLUDE_DIR}")
87 | MESSAGE(STATUS "MKL_LIB_DIR: ${MKL_LIB_DIR}")
88 | MESSAGE(STATUS "MKL_COMPILER_LIB_DIR: ${MKL_COMPILER_LIB_DIR}")
89 | ENDIF (NOT MKL_FIND_QUIETLY)
90 |
91 | INCLUDE_DIRECTORIES( ${MKL_INCLUDE_DIR} )
92 | LINK_DIRECTORIES( ${MKL_LIB_DIR} ${MKL_COMPILER_LIB_DIR} )
93 | ELSE (MKL_FOUND)
94 | IF (MKL_FIND_REQUIRED)
95 | MESSAGE(FATAL_ERROR "Could not find MKL libraries")
96 | ENDIF (MKL_FIND_REQUIRED)
97 | ENDIF (MKL_FOUND)
98 |
99 | # MARK_AS_ADVANCED(MKL_LIBRARY)
--------------------------------------------------------------------------------
/cmake/findThreads.cmake:
--------------------------------------------------------------------------------
1 | # Updated FindThreads.cmake that supports pthread-win32
2 | # Downloaded from http://www.vtk.org/Bug/bug_view_advanced_page.php?bug_id=6399
3 |
4 | # - This module determines the thread library of the system.
5 | #
6 | # The following variables are set
7 | # CMAKE_THREAD_LIBS_INIT - the thread library
8 | # CMAKE_USE_SPROC_INIT - are we using sproc?
9 | # CMAKE_USE_WIN32_THREADS_INIT - using WIN32 threads?
10 | # CMAKE_USE_PTHREADS_INIT - are we using pthreads
11 | # CMAKE_HP_PTHREADS_INIT - are we using hp pthreads
12 | #
13 | # If use of pthreads-win32 is desired, the following variables
14 | # can be set.
15 | #
16 | # THREADS_USE_PTHREADS_WIN32 -
17 | # Setting this to true searches for the pthreads-win32
18 | # port (since CMake 2.8.0)
19 | #
20 | # THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME
21 | # C = no exceptions (default)
22 | # (NOTE: This is the default scheme on most POSIX thread
23 | # implementations and what you should probably be using)
24 | # CE = C++ Exception Handling
25 | # SE = Structure Exception Handling (MSVC only)
26 | # (NOTE: Changing this option from the default may affect
27 | # the portability of your application. See pthreads-win32
28 | # documentation for more details.)
29 | #
30 | #======================================================
31 | # Example usage where threading library
32 | # is provided by the system:
33 | #
34 | # find_package(Threads REQUIRED)
35 | # add_executable(foo foo.cc)
36 | # target_link_libraries(foo ${CMAKE_THREAD_LIBS_INIT})
37 | #
38 | # Example usage if pthreads-win32 is desired on Windows
39 | # or a system provided thread library:
40 | #
41 | # set(THREADS_USE_PTHREADS_WIN32 true)
42 | # find_package(Threads REQUIRED)
43 | # include_directories(${THREADS_PTHREADS_INCLUDE_DIR})
44 | #
45 | # add_executable(foo foo.cc)
46 | # target_link_libraries(foo ${CMAKE_THREAD_LIBS_INIT})
47 | #
48 |
49 | INCLUDE (CheckIncludeFiles)
50 | INCLUDE (CheckLibraryExists)
51 | SET(Threads_FOUND FALSE)
52 |
53 | IF(WIN32 AND NOT CYGWIN AND THREADS_USE_PTHREADS_WIN32)
54 | SET(_Threads_ptwin32 true)
55 | ENDIF()
56 |
57 | # Do we have sproc?
58 | IF(CMAKE_SYSTEM MATCHES IRIX)
59 | CHECK_INCLUDE_FILES("sys/types.h;sys/prctl.h" CMAKE_HAVE_SPROC_H)
60 | ENDIF()
61 |
62 | IF(CMAKE_HAVE_SPROC_H)
63 | # We have sproc
64 | SET(CMAKE_USE_SPROC_INIT 1)
65 |
66 | ELSEIF(_Threads_ptwin32)
67 |
68 | IF(NOT DEFINED THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME)
69 | # Assign the default scheme
70 | SET(THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME "C")
71 | ELSE()
72 | # Validate the scheme specified by the user
73 | IF(NOT THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME STREQUAL "C" AND
74 | NOT THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME STREQUAL "CE" AND
75 | NOT THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME STREQUAL "SE")
76 | MESSAGE(FATAL_ERROR "See documentation for FindPthreads.cmake, only C, CE, and SE modes are allowed")
77 | ENDIF()
78 | IF(NOT MSVC AND THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME STREQUAL "SE")
79 | MESSAGE(FATAL_ERROR "Structured Exception Handling is only allowed for MSVC")
80 | ENDIF(NOT MSVC AND THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME STREQUAL "SE")
81 | ENDIF()
82 |
83 | FIND_PATH(THREADS_PTHREADS_INCLUDE_DIR
84 | pthread.h
85 | PATHS
86 | ${THREADS_PTHREAD_WIN32_INC}
87 | )
88 |
89 | # Determine the library filename
90 | IF(MSVC)
91 | SET(_Threads_pthreads_libname
92 | pthreadV${THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME}2)
93 | ELSEIF(MINGW)
94 | SET(_Threads_pthreads_libname
95 | pthreadG${THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME}2)
96 | ELSE()
97 | SET(_Threads_pthreads_libname
98 | pthreadV${THREADS_PTHREADS_WIN32_EXCEPTION_SCHEME}2)
99 | ENDIF()
100 |
101 | # Use the include path to help find the library if possible
102 | SET(_Threads_lib_paths "")
103 | IF(THREADS_PTHREADS_INCLUDE_DIR)
104 | GET_FILENAME_COMPONENT(_Threads_root_dir
105 | ${THREADS_PTHREADS_INCLUDE_DIR} PATH)
106 | SET(_Threads_lib_paths ${_Threads_root_dir}/lib/x64)
107 | ENDIF()
108 | FIND_LIBRARY(THREADS_PTHREADS_WIN32_LIBRARY
109 | NAMES ${_Threads_pthreads_libname}
110 | PATHS ${_Threads_lib_paths}
111 | DOC "The Portable Threads Library for Win32"
112 | NO_SYSTEM_PATH
113 | )
114 |
115 | IF(THREADS_PTHREADS_INCLUDE_DIR AND THREADS_PTHREADS_WIN32_LIBRARY)
116 | MARK_AS_ADVANCED(THREADS_PTHREADS_INCLUDE_DIR)
117 | SET(CMAKE_THREAD_LIBS_INIT ${THREADS_PTHREADS_WIN32_LIBRARY})
118 | SET(CMAKE_HAVE_THREADS_LIBRARY 1)
119 | SET(Threads_FOUND TRUE)
120 | ENDIF()
121 |
122 | MARK_AS_ADVANCED(THREADS_PTHREADS_WIN32_LIBRARY)
123 |
124 | ELSE()
125 | # Do we have pthreads?
126 | CHECK_INCLUDE_FILES("pthread.h" CMAKE_HAVE_PTHREAD_H)
127 | IF(CMAKE_HAVE_PTHREAD_H)
128 |
129 | #
130 | # We have pthread.h
131 | # Let's check for the library now.
132 | #
133 | SET(CMAKE_HAVE_THREADS_LIBRARY)
134 | IF(NOT THREADS_HAVE_PTHREAD_ARG)
135 |
136 | # Do we have -lpthreads
137 | CHECK_LIBRARY_EXISTS(pthreads pthread_create "" CMAKE_HAVE_PTHREADS_CREATE)
138 | IF(CMAKE_HAVE_PTHREADS_CREATE)
139 | SET(CMAKE_THREAD_LIBS_INIT "-lpthreads")
140 | SET(CMAKE_HAVE_THREADS_LIBRARY 1)
141 | SET(Threads_FOUND TRUE)
142 | ENDIF()
143 |
144 | # Ok, how about -lpthread
145 | CHECK_LIBRARY_EXISTS(pthread pthread_create "" CMAKE_HAVE_PTHREAD_CREATE)
146 | IF(CMAKE_HAVE_PTHREAD_CREATE)
147 | SET(CMAKE_THREAD_LIBS_INIT "-lpthread")
148 | SET(Threads_FOUND TRUE)
149 | SET(CMAKE_HAVE_THREADS_LIBRARY 1)
150 | ENDIF()
151 |
152 | IF(CMAKE_SYSTEM MATCHES "SunOS.*")
153 | # On sun also check for -lthread
154 | CHECK_LIBRARY_EXISTS(thread thr_create "" CMAKE_HAVE_THR_CREATE)
155 | IF(CMAKE_HAVE_THR_CREATE)
156 | SET(CMAKE_THREAD_LIBS_INIT "-lthread")
157 | SET(CMAKE_HAVE_THREADS_LIBRARY 1)
158 | SET(Threads_FOUND TRUE)
159 | ENDIF()
160 | ENDIF(CMAKE_SYSTEM MATCHES "SunOS.*")
161 |
162 | ENDIF(NOT THREADS_HAVE_PTHREAD_ARG)
163 |
164 | IF(NOT CMAKE_HAVE_THREADS_LIBRARY)
165 | # If we did not found -lpthread, -lpthread, or -lthread, look for -pthread
166 | IF("THREADS_HAVE_PTHREAD_ARG" MATCHES "^THREADS_HAVE_PTHREAD_ARG")
167 | MESSAGE(STATUS "Check if compiler accepts -pthread")
168 | TRY_RUN(THREADS_PTHREAD_ARG THREADS_HAVE_PTHREAD_ARG
169 | ${CMAKE_BINARY_DIR}
170 | ${CMAKE_ROOT}/Modules/CheckForPthreads.c
171 | CMAKE_FLAGS -DLINK_LIBRARIES:STRING=-pthread
172 | COMPILE_OUTPUT_VARIABLE OUTPUT)
173 |
174 | IF(THREADS_HAVE_PTHREAD_ARG)
175 | IF(THREADS_PTHREAD_ARG MATCHES "^2$")
176 | SET(Threads_FOUND TRUE)
177 | MESSAGE(STATUS "Check if compiler accepts -pthread - yes")
178 | ELSE()
179 | MESSAGE(STATUS "Check if compiler accepts -pthread - no")
180 | FILE(APPEND
181 | ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
182 | "Determining if compiler accepts -pthread returned ${THREADS_PTHREAD_ARG} instead of 2. The compiler had the following output:\n${OUTPUT}\n\n")
183 | ENDIF()
184 | ELSE()
185 | MESSAGE(STATUS "Check if compiler accepts -pthread - no")
186 | FILE(APPEND
187 | ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
188 | "Determining if compiler accepts -pthread failed with the following output:\n${OUTPUT}\n\n")
189 | ENDIF()
190 |
191 | ENDIF("THREADS_HAVE_PTHREAD_ARG" MATCHES "^THREADS_HAVE_PTHREAD_ARG")
192 |
193 | IF(THREADS_HAVE_PTHREAD_ARG)
194 | SET(Threads_FOUND TRUE)
195 | SET(CMAKE_THREAD_LIBS_INIT "-pthread")
196 | ENDIF()
197 |
198 | ENDIF(NOT CMAKE_HAVE_THREADS_LIBRARY)
199 | ENDIF(CMAKE_HAVE_PTHREAD_H)
200 | ENDIF()
201 |
202 | IF(CMAKE_THREAD_LIBS_INIT)
203 | SET(CMAKE_USE_PTHREADS_INIT 1)
204 | SET(Threads_FOUND TRUE)
205 | ENDIF()
206 |
207 | IF(CMAKE_SYSTEM MATCHES "Windows"
208 | AND NOT THREADS_USE_PTHREADS_WIN32)
209 | SET(CMAKE_USE_WIN32_THREADS_INIT 1)
210 | SET(Threads_FOUND TRUE)
211 | ENDIF()
212 |
213 | IF(CMAKE_USE_PTHREADS_INIT)
214 | IF(CMAKE_SYSTEM MATCHES "HP-UX-*")
215 | # Use libcma if it exists and can be used. It provides more
216 | # symbols than the plain pthread library. CMA threads
217 | # have actually been deprecated:
218 | # http://docs.hp.com/en/B3920-90091/ch12s03.html#d0e11395
219 | # http://docs.hp.com/en/947/d8.html
220 | # but we need to maintain compatibility here.
221 | # The CMAKE_HP_PTHREADS setting actually indicates whether CMA threads
222 | # are available.
223 | CHECK_LIBRARY_EXISTS(cma pthread_attr_create "" CMAKE_HAVE_HP_CMA)
224 | IF(CMAKE_HAVE_HP_CMA)
225 | SET(CMAKE_THREAD_LIBS_INIT "-lcma")
226 | SET(CMAKE_HP_PTHREADS_INIT 1)
227 | SET(Threads_FOUND TRUE)
228 | ENDIF(CMAKE_HAVE_HP_CMA)
229 | SET(CMAKE_USE_PTHREADS_INIT 1)
230 | ENDIF()
231 |
232 | IF(CMAKE_SYSTEM MATCHES "OSF1-V*")
233 | SET(CMAKE_USE_PTHREADS_INIT 0)
234 | SET(CMAKE_THREAD_LIBS_INIT )
235 | ENDIF()
236 |
237 | IF(CMAKE_SYSTEM MATCHES "CYGWIN_NT*")
238 | SET(CMAKE_USE_PTHREADS_INIT 1)
239 | SET(Threads_FOUND TRUE)
240 | SET(CMAKE_THREAD_LIBS_INIT )
241 | SET(CMAKE_USE_WIN32_THREADS_INIT 0)
242 | ENDIF()
243 | ENDIF(CMAKE_USE_PTHREADS_INIT)
244 |
245 | INCLUDE(FindPackageHandleStandardArgs)
246 | IF(_Threads_ptwin32)
247 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Threads DEFAULT_MSG
248 | THREADS_PTHREADS_WIN32_LIBRARY THREADS_PTHREADS_INCLUDE_DIR)
249 | ELSE()
250 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(Threads DEFAULT_MSG Threads_FOUND)
251 | ENDIF()
--------------------------------------------------------------------------------
/convdata.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
2 | # All rights reserved.
3 | #
4 | # Redistribution and use in source and binary forms, with or without modification,
5 | # are permitted provided that the following conditions are met:
6 | #
7 | # - Redistributions of source code must retain the above copyright notice,
8 | # this list of conditions and the following disclaimer.
9 | #
10 | # - Redistributions in binary form must reproduce the above copyright notice,
11 | # this list of conditions and the following disclaimer in the documentation
12 | # and/or other materials provided with the distribution.
13 | #
14 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
25 | from data import *
26 | import numpy.random as nr
27 | import numpy as n
28 | import random as r
29 |
30 | class CIFARDataProvider(LabeledMemoryDataProvider):
31 | def __init__(self, data_dir, batch_range, init_epoch=1, init_batchnum=None, dp_params={}, test=False):
32 | LabeledMemoryDataProvider.__init__(self, data_dir, batch_range, init_epoch, init_batchnum, dp_params, test)
33 | self.data_mean = self.batch_meta['data_mean']
34 | self.num_colors = 3
35 | self.img_size = 32
36 | # Subtract the mean from the data and make sure that both data and
37 | # labels are in single-precision floating point.
38 | for d in self.data_dic:
39 | # This converts the data matrix to single precision and makes sure that it is C-ordered
40 | d['data'] = n.require((d['data'] - self.data_mean), dtype=n.single, requirements='C')
41 | d['labels'] = n.require(d['labels'].reshape((1, d['data'].shape[1])), dtype=n.single, requirements='C')
42 |
43 | def get_next_batch(self):
44 | epoch, batchnum, datadic = LabeledMemoryDataProvider.get_next_batch(self)
45 | return epoch, batchnum, [datadic['data'], datadic['labels']]
46 |
47 | # Returns the dimensionality of the two data matrices returned by get_next_batch
48 | # idx is the index of the matrix.
49 | def get_data_dims(self, idx=0):
50 | return self.img_size**2 * self.num_colors if idx == 0 else 1
51 |
52 | # Takes as input an array returned by get_next_batch
53 | # Returns a (numCases, imgSize, imgSize, 3) array which can be
54 | # fed to pylab for plotting.
55 | # This is used by shownet.py to plot test case predictions.
56 | def get_plottable_data(self, data):
57 | return n.require((data + self.data_mean).T.reshape(data.shape[1], 3, self.img_size, self.img_size).swapaxes(1,3).swapaxes(1,2) / 255.0, dtype=n.single)
58 |
59 | class CroppedCIFARDataProvider(LabeledMemoryDataProvider):
60 | def __init__(self, data_dir, batch_range=None, init_epoch=1, init_batchnum=None, dp_params=None, test=False):
61 | LabeledMemoryDataProvider.__init__(self, data_dir, batch_range, init_epoch, init_batchnum, dp_params, test)
62 |
63 | self.border_size = dp_params['crop_border']
64 | self.inner_size = 32 - self.border_size*2
65 | self.multiview = dp_params['multiview_test'] and test
66 | self.num_views = 5*2
67 | self.data_mult = self.num_views if self.multiview else 1
68 | self.num_colors = 3
69 |
70 | for d in self.data_dic:
71 | d['data'] = n.require(d['data'], requirements='C')
72 | d['labels'] = n.require(n.tile(d['labels'].reshape((1, d['data'].shape[1])), (1, self.data_mult)), requirements='C')
73 |
74 | self.cropped_data = [n.zeros((self.get_data_dims(), self.data_dic[0]['data'].shape[1]*self.data_mult), dtype=n.single) for x in xrange(2)]
75 |
76 | self.batches_generated = 0
77 | self.data_mean = self.batch_meta['data_mean'].reshape((3,32,32))[:,self.border_size:self.border_size+self.inner_size,self.border_size:self.border_size+self.inner_size].reshape((self.get_data_dims(), 1))
78 |
79 | def get_next_batch(self):
80 | epoch, batchnum, datadic = LabeledMemoryDataProvider.get_next_batch(self)
81 |
82 | cropped = self.cropped_data[self.batches_generated % 2]
83 |
84 | self.__trim_borders(datadic['data'], cropped)
85 | cropped -= self.data_mean
86 | self.batches_generated += 1
87 | return epoch, batchnum, [cropped, datadic['labels']]
88 |
89 | def get_data_dims(self, idx=0):
90 | return self.inner_size**2 * 3 if idx == 0 else 1
91 |
92 | # Takes as input an array returned by get_next_batch
93 | # Returns a (numCases, imgSize, imgSize, 3) array which can be
94 | # fed to pylab for plotting.
95 | # This is used by shownet.py to plot test case predictions.
96 | def get_plottable_data(self, data):
97 | return n.require((data + self.data_mean).T.reshape(data.shape[1], 3, self.inner_size, self.inner_size).swapaxes(1,3).swapaxes(1,2) / 255.0, dtype=n.single)
98 |
99 | def __trim_borders(self, x, target):
100 | y = x.reshape(3, 32, 32, x.shape[1])
101 |
102 | if self.test: # don't need to loop over cases
103 | if self.multiview:
104 | start_positions = [(0,0), (0, self.border_size*2),
105 | (self.border_size, self.border_size),
106 | (self.border_size*2, 0), (self.border_size*2, self.border_size*2)]
107 | end_positions = [(sy+self.inner_size, sx+self.inner_size) for (sy,sx) in start_positions]
108 | for i in xrange(self.num_views/2):
109 | pic = y[:,start_positions[i][0]:end_positions[i][0],start_positions[i][1]:end_positions[i][1],:]
110 | target[:,i * x.shape[1]:(i+1)* x.shape[1]] = pic.reshape((self.get_data_dims(),x.shape[1]))
111 | target[:,(self.num_views/2 + i) * x.shape[1]:(self.num_views/2 +i+1)* x.shape[1]] = pic[:,:,::-1,:].reshape((self.get_data_dims(),x.shape[1]))
112 | else:
113 | pic = y[:,self.border_size:self.border_size+self.inner_size,self.border_size:self.border_size+self.inner_size, :] # just take the center for now
114 | target[:,:] = pic.reshape((self.get_data_dims(), x.shape[1]))
115 | else:
116 | for c in xrange(x.shape[1]): # loop over cases
117 | startY, startX = nr.randint(0,self.border_size*2 + 1), nr.randint(0,self.border_size*2 + 1)
118 | endY, endX = startY + self.inner_size, startX + self.inner_size
119 | pic = y[:,startY:endY,startX:endX, c]
120 | if nr.randint(2) == 0: # also flip the image with 50% probability
121 | pic = pic[:,:,::-1]
122 | target[:,c] = pic.reshape((self.get_data_dims(),))
123 |
124 | class DummyConvNetDataProvider(LabeledDummyDataProvider):
125 | def __init__(self, data_dim):
126 | LabeledDummyDataProvider.__init__(self, data_dim)
127 |
128 | def get_next_batch(self):
129 | epoch, batchnum, dic = LabeledDummyDataProvider.get_next_batch(self)
130 |
131 | dic['data'] = n.require(dic['data'].T, requirements='C')
132 | dic['labels'] = n.require(dic['labels'].T, requirements='C')
133 |
134 | return epoch, batchnum, [dic['data'], dic['labels']]
135 |
136 | # Returns the dimensionality of the two data matrices returned by get_next_batch
137 | def get_data_dims(self, idx=0):
138 | return self.batch_meta['num_vis'] if idx == 0 else 1
139 |
--------------------------------------------------------------------------------
/convnet.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
2 | # All rights reserved.
3 | #
4 | # Redistribution and use in source and binary forms, with or without modification,
5 | # are permitted provided that the following conditions are met:
6 | #
7 | # - Redistributions of source code must retain the above copyright notice,
8 | # this list of conditions and the following disclaimer.
9 | #
10 | # - Redistributions in binary form must reproduce the above copyright notice,
11 | # this list of conditions and the following disclaimer in the documentation
12 | # and/or other materials provided with the distribution.
13 | #
14 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
25 | import numpy as n
26 | import numpy.random as nr
27 | from util import *
28 | from data import *
29 | from options import *
30 | from gpumodel import *
31 | import sys
32 | import math as m
33 | import layer as lay
34 | from convdata import *
35 | from os import linesep as NL
36 | #import pylab as pl
37 |
38 | class ConvNet(IGPUModel):
39 | def __init__(self, op, load_dic, dp_params={}):
40 | filename_options = []
41 | dp_params['multiview_test'] = op.get_value('multiview_test')
42 | dp_params['crop_border'] = op.get_value('crop_border')
43 | IGPUModel.__init__(self, "ConvNet", op, load_dic, filename_options, dp_params=dp_params)
44 |
45 | def import_model(self):
46 | lib_name = "_convnet"
47 | print "========================="
48 | print "Importing %s C++ module" % lib_name
49 | self.libmodel = __import__(lib_name)
50 |
51 | def init_model_lib(self):
52 | self.libmodel.initModel(self.layers, self.minibatch_size, self.device_ids[0])
53 |
54 | def init_model_state(self):
55 | ms = self.model_state
56 | if self.load_file:
57 | ms['layers'] = lay.LayerParser.parse_layers(self.layer_def, self.layer_params, self, ms['layers'])
58 | else:
59 | ms['layers'] = lay.LayerParser.parse_layers(self.layer_def, self.layer_params, self)
60 | self.layers_dic = dict(zip([l['name'] for l in ms['layers']], ms['layers']))
61 |
62 | logreg_name = self.op.get_value('logreg_name')
63 | if logreg_name:
64 | self.logreg_idx = self.get_layer_idx(logreg_name, check_type='cost.logreg')
65 |
66 | # Convert convolutional layers to local
67 | if len(self.op.get_value('conv_to_local')) > 0:
68 | for i, layer in enumerate(ms['layers']):
69 | if layer['type'] == 'conv' and layer['name'] in self.op.get_value('conv_to_local'):
70 | lay.LocalLayerParser.conv_to_local(ms['layers'], i)
71 | # Decouple weight matrices
72 | if len(self.op.get_value('unshare_weights')) > 0:
73 | for name_str in self.op.get_value('unshare_weights'):
74 | if name_str:
75 | name = lay.WeightLayerParser.get_layer_name(name_str)
76 | if name is not None:
77 | name, idx = name[0], name[1]
78 | if name not in self.layers_dic:
79 | raise ModelStateException("Layer '%s' does not exist; unable to unshare" % name)
80 | layer = self.layers_dic[name]
81 | lay.WeightLayerParser.unshare_weights(layer, ms['layers'], matrix_idx=idx)
82 | else:
83 | raise ModelStateException("Invalid layer name '%s'; unable to unshare." % name_str)
84 | self.op.set_value('conv_to_local', [], parse=False)
85 | self.op.set_value('unshare_weights', [], parse=False)
86 |
87 | def get_layer_idx(self, layer_name, check_type=None):
88 | try:
89 | layer_idx = [l['name'] for l in self.model_state['layers']].index(layer_name)
90 | if check_type:
91 | layer_type = self.model_state['layers'][layer_idx]['type']
92 | if layer_type != check_type:
93 | raise ModelStateException("Layer with name '%s' has type '%s'; should be '%s'." % (layer_name, layer_type, check_type))
94 | return layer_idx
95 | except ValueError:
96 | raise ModelStateException("Layer with name '%s' not defined." % layer_name)
97 |
98 | def fill_excused_options(self):
99 | if self.op.get_value('check_grads'):
100 | self.op.set_value('save_path', '')
101 | self.op.set_value('train_batch_range', '0')
102 | self.op.set_value('test_batch_range', '0')
103 | self.op.set_value('data_path', '')
104 |
105 | # Make sure the data provider returned data in proper format
106 | def parse_batch_data(self, batch_data, train=True):
107 | if max(d.dtype != n.single for d in batch_data[2]):
108 | raise DataProviderException("All matrices returned by data provider must consist of single-precision floats.")
109 | return batch_data
110 |
111 | def start_batch(self, batch_data, train=True):
112 | data = batch_data[2]
113 | if self.check_grads:
114 | self.libmodel.checkGradients(data)
115 | elif not train and self.multiview_test:
116 | self.libmodel.startMultiviewTest(data, self.train_data_provider.num_views, self.logreg_idx)
117 | else:
118 | self.libmodel.startBatch(data, not train)
119 |
120 | def print_iteration(self):
121 | print "%d.%d..." % (self.epoch, self.batchnum),
122 |
123 | def print_train_time(self, compute_time_py):
124 | print "(%.3f sec)" % (compute_time_py)
125 |
126 | def print_costs(self, cost_outputs):
127 | costs, num_cases = cost_outputs[0], cost_outputs[1]
128 | for errname in costs.keys():
129 | costs[errname] = [(v/num_cases) for v in costs[errname]]
130 | print "%s: " % errname,
131 | print ", ".join("%6f" % v for v in costs[errname]),
132 | if sum(m.isnan(v) for v in costs[errname]) > 0 or sum(m.isinf(v) for v in costs[errname]):
133 | print "^ got nan or inf!"
134 | sys.exit(1)
135 |
136 | def print_train_results(self):
137 | self.print_costs(self.train_outputs[-1])
138 |
139 | def print_test_status(self):
140 | pass
141 |
142 | def print_test_results(self):
143 | print ""
144 | print "======================Test output======================"
145 | self.print_costs(self.test_outputs[-1])
146 | print ""
147 | print "-------------------------------------------------------",
148 | for i,l in enumerate(self.layers): # This is kind of hacky but will do for now.
149 | if 'weights' in l:
150 | if type(l['weights']) == n.ndarray:
151 | print "%sLayer '%s' weights: %e [%e]" % (NL, l['name'], n.mean(n.abs(l['weights'])), n.mean(n.abs(l['weightsInc']))),
152 | elif type(l['weights']) == list:
153 | print ""
154 | print NL.join("Layer '%s' weights[%d]: %e [%e]" % (l['name'], i, n.mean(n.abs(w)), n.mean(n.abs(wi))) for i,(w,wi) in enumerate(zip(l['weights'],l['weightsInc']))),
155 | print "%sLayer '%s' biases: %e [%e]" % (NL, l['name'], n.mean(n.abs(l['biases'])), n.mean(n.abs(l['biasesInc']))),
156 | print ""
157 |
158 | def conditional_save(self):
159 | self.save_state()
160 | print "-------------------------------------------------------"
161 | print "Saved checkpoint to %s" % os.path.join(self.save_path, self.save_file)
162 | print "=======================================================",
163 |
164 | def aggregate_test_outputs(self, test_outputs):
165 | num_cases = sum(t[1] for t in test_outputs)
166 | for i in xrange(1 ,len(test_outputs)):
167 | for k,v in test_outputs[i][0].items():
168 | for j in xrange(len(v)):
169 | test_outputs[0][0][k][j] += test_outputs[i][0][k][j]
170 | return (test_outputs[0][0], num_cases)
171 |
172 | @classmethod
173 | def get_options_parser(cls):
174 | op = IGPUModel.get_options_parser()
175 | op.add_option("mini", "minibatch_size", IntegerOptionParser, "Minibatch size", default=128)
176 | op.add_option("layer-def", "layer_def", StringOptionParser, "Layer definition file", set_once=True)
177 | op.add_option("layer-params", "layer_params", StringOptionParser, "Layer parameter file")
178 | op.add_option("check-grads", "check_grads", BooleanOptionParser, "Check gradients and quit?", default=0, excuses=['data_path','save_path','train_batch_range','test_batch_range'])
179 | op.add_option("multiview-test", "multiview_test", BooleanOptionParser, "Cropped DP: test on multiple patches?", default=0, requires=['logreg_name'])
180 | op.add_option("crop-border", "crop_border", IntegerOptionParser, "Cropped DP: crop border size", default=4, set_once=True)
181 | op.add_option("logreg-name", "logreg_name", StringOptionParser, "Cropped DP: logreg layer name (for --multiview-test)", default="")
182 | op.add_option("conv-to-local", "conv_to_local", ListOptionParser(StringOptionParser), "Convert given conv layers to unshared local", default=[])
183 | op.add_option("unshare-weights", "unshare_weights", ListOptionParser(StringOptionParser), "Unshare weight matrices in given layers", default=[])
184 | op.add_option("conserve-mem", "conserve_mem", BooleanOptionParser, "Conserve GPU memory (slower)?", default=0)
185 |
186 | op.delete_option('max_test_err')
187 | op.options["max_filesize_mb"].default = 0
188 | op.options["testing_freq"].default = 50
189 | op.options["num_epochs"].default = 50000
190 | op.options['dp_type'].default = None
191 |
192 | DataProvider.register_data_provider('cifar', 'CIFAR', CIFARDataProvider)
193 | DataProvider.register_data_provider('dummy-cn-n', 'Dummy ConvNet', DummyConvNetDataProvider)
194 | DataProvider.register_data_provider('cifar-cropped', 'Cropped CIFAR', CroppedCIFARDataProvider)
195 |
196 | return op
197 |
198 | if __name__ == "__main__":
199 | #nr.seed(5)
200 | op = ConvNet.get_options_parser()
201 |
202 | op, load_dic = IGPUModel.parse_options(op)
203 | model = ConvNet(op, load_dic)
204 | model.start()
205 |
--------------------------------------------------------------------------------
/data.py:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
2 | # All rights reserved.
3 | #
4 | # Redistribution and use in source and binary forms, with or without modification,
5 | # are permitted provided that the following conditions are met:
6 | #
7 | # - Redistributions of source code must retain the above copyright notice,
8 | # this list of conditions and the following disclaimer.
9 | #
10 | # - Redistributions in binary form must reproduce the above copyright notice,
11 | # this list of conditions and the following disclaimer in the documentation
12 | # and/or other materials provided with the distribution.
13 | #
14 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 | # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 | # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23 | # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
25 | import numpy as n
26 | from numpy.random import randn, rand, random_integers
27 | import os
28 | from util import *
29 |
30 | BATCH_META_FILE = "batches.meta"
31 |
32 | class DataProvider:
33 | BATCH_REGEX = re.compile('^data_batch_(\d+)(\.\d+)?$')
34 | def __init__(self, data_dir, batch_range=None, init_epoch=1, init_batchnum=None, dp_params={}, test=False):
35 | if batch_range == None:
36 | batch_range = DataProvider.get_batch_nums(data_dir)
37 | if init_batchnum is None or init_batchnum not in batch_range:
38 | init_batchnum = batch_range[0]
39 |
40 | self.data_dir = data_dir
41 | self.batch_range = batch_range
42 | self.curr_epoch = init_epoch
43 | self.curr_batchnum = init_batchnum
44 | self.dp_params = dp_params
45 | self.batch_meta = self.get_batch_meta(data_dir)
46 | self.data_dic = None
47 | self.test = test
48 | self.batch_idx = batch_range.index(init_batchnum)
49 |
50 | def get_next_batch(self):
51 | if self.data_dic is None or len(self.batch_range) > 1:
52 | self.data_dic = self.get_batch(self.curr_batchnum)
53 | epoch, batchnum = self.curr_epoch, self.curr_batchnum
54 | self.advance_batch()
55 |
56 | return epoch, batchnum, self.data_dic
57 |
58 | def __add_subbatch(self, batch_num, sub_batchnum, batch_dic):
59 | subbatch_path = "%s.%d" % (os.path.join(self.data_dir, self.get_data_file_name(batch_num)), sub_batchnum)
60 | if os.path.exists(subbatch_path):
61 | sub_dic = unpickle(subbatch_path)
62 | self._join_batches(batch_dic, sub_dic)
63 | else:
64 | raise IndexError("Sub-batch %d.%d does not exist in %s" % (batch_num,sub_batchnum, self.data_dir))
65 |
66 | def _join_batches(self, main_batch, sub_batch):
67 | main_batch['data'] = n.r_[main_batch['data'], sub_batch['data']]
68 |
69 | def get_batch(self, batch_num):
70 | if os.path.exists(self.get_data_file_name(batch_num) + '.1'): # batch in sub-batches
71 | dic = unpickle(self.get_data_file_name(batch_num) + '.1')
72 | sb_idx = 2
73 | while True:
74 | try:
75 | self.__add_subbatch(batch_num, sb_idx, dic)
76 | sb_idx += 1
77 | except IndexError:
78 | break
79 | else:
80 | dic = unpickle(self.get_data_file_name(batch_num))
81 | return dic
82 |
83 | def get_data_dims(self):
84 | return self.batch_meta['num_vis']
85 |
86 | def advance_batch(self):
87 | self.batch_idx = self.get_next_batch_idx()
88 | self.curr_batchnum = self.batch_range[self.batch_idx]
89 | if self.batch_idx == 0: # we wrapped
90 | self.curr_epoch += 1
91 |
92 | def get_next_batch_idx(self):
93 | return (self.batch_idx + 1) % len(self.batch_range)
94 |
95 | def get_next_batch_num(self):
96 | return self.batch_range[self.get_next_batch_idx()]
97 |
98 | # get filename of current batch
99 | def get_data_file_name(self, batchnum=None):
100 | if batchnum is None:
101 | batchnum = self.curr_batchnum
102 | return os.path.join(self.data_dir, 'data_batch_%d' % batchnum)
103 |
104 | @classmethod
105 | def get_instance(cls, data_dir, batch_range=None, init_epoch=1, init_batchnum=None, type="default", dp_params={}, test=False):
106 | # why the fuck can't i reference DataProvider in the original definition?
107 | #cls.dp_classes['default'] = DataProvider
108 | type = type or DataProvider.get_batch_meta(data_dir)['dp_type'] # allow data to decide data provider
109 | if type.startswith("dummy-"):
110 | name = "-".join(type.split('-')[:-1]) + "-n"
111 | if name not in dp_types:
112 | raise DataProviderException("No such data provider: %s" % type)
113 | _class = dp_classes[name]
114 | dims = int(type.split('-')[-1])
115 | return _class(dims)
116 | elif type in dp_types:
117 | _class = dp_classes[type]
118 | return _class(data_dir, batch_range, init_epoch, init_batchnum, dp_params, test)
119 |
120 | raise DataProviderException("No such data provider: %s" % type)
121 |
122 | @classmethod
123 | def register_data_provider(cls, name, desc, _class):
124 | if name in dp_types:
125 | raise DataProviderException("Data provider %s already registered" % name)
126 | dp_types[name] = desc
127 | dp_classes[name] = _class
128 |
129 | @staticmethod
130 | def get_batch_meta(data_dir):
131 | return unpickle(os.path.join(data_dir, BATCH_META_FILE))
132 |
133 | @staticmethod
134 | def get_batch_filenames(srcdir):
135 | return sorted([f for f in os.listdir(srcdir) if DataProvider.BATCH_REGEX.match(f)], key=alphanum_key)
136 |
137 | @staticmethod
138 | def get_batch_nums(srcdir):
139 | names = DataProvider.get_batch_filenames(srcdir)
140 | return sorted(list(set(int(DataProvider.BATCH_REGEX.match(n).group(1)) for n in names)))
141 |
142 | @staticmethod
143 | def get_num_batches(srcdir):
144 | return len(DataProvider.get_batch_nums(srcdir))
145 |
146 | class DummyDataProvider(DataProvider):
147 | def __init__(self, data_dim):
148 | #self.data_dim = data_dim
149 | self.batch_range = [1]
150 | self.batch_meta = {'num_vis': data_dim, 'data_in_rows':True}
151 | self.curr_epoch = 1
152 | self.curr_batchnum = 1
153 | self.batch_idx = 0
154 |
155 | def get_next_batch(self):
156 | epoch, batchnum = self.curr_epoch, self.curr_batchnum
157 | self.advance_batch()
158 | data = rand(512, self.get_data_dims()).astype(n.single)
159 | return self.curr_epoch, self.curr_batchnum, {'data':data}
160 |
161 |
162 | class LabeledDummyDataProvider(DummyDataProvider):
163 | def __init__(self, data_dim, num_classes=10, num_cases=512):
164 | #self.data_dim = data_dim
165 | self.batch_range = [1]
166 | self.batch_meta = {'num_vis': data_dim,
167 | 'label_names': [str(x) for x in range(num_classes)],
168 | 'data_in_rows':True}
169 | self.num_cases = num_cases
170 | self.num_classes = num_classes
171 | self.curr_epoch = 1
172 | self.curr_batchnum = 1
173 | self.batch_idx=0
174 |
175 | def get_num_classes(self):
176 | return self.num_classes
177 |
178 | def get_next_batch(self):
179 | epoch, batchnum = self.curr_epoch, self.curr_batchnum
180 | self.advance_batch()
181 | data = rand(self.num_cases, self.get_data_dims()).astype(n.single) # <--changed to rand
182 | labels = n.require(n.c_[random_integers(0,self.num_classes-1,self.num_cases)], requirements='C', dtype=n.single)
183 |
184 | return self.curr_epoch, self.curr_batchnum, {'data':data, 'labels':labels}
185 |
186 | class MemoryDataProvider(DataProvider):
187 | def __init__(self, data_dir, batch_range, init_epoch=1, init_batchnum=None, dp_params=None, test=False):
188 | DataProvider.__init__(self, data_dir, batch_range, init_epoch, init_batchnum, dp_params, test)
189 | self.data_dic = []
190 | for i in self.batch_range:
191 | self.data_dic += [self.get_batch(i)]
192 |
193 | def get_next_batch(self):
194 | epoch, batchnum = self.curr_epoch, self.curr_batchnum
195 | self.advance_batch()
196 |
197 | return epoch, batchnum, self.data_dic[batchnum - self.batch_range[0]]
198 |
199 | class LabeledDataProvider(DataProvider):
200 | def __init__(self, data_dir, batch_range=None, init_epoch=1, init_batchnum=None, dp_params={}, test=False):
201 | DataProvider.__init__(self, data_dir, batch_range, init_epoch, init_batchnum, dp_params, test)
202 |
203 | def get_num_classes(self):
204 | return len(self.batch_meta['label_names'])
205 |
206 | class LabeledMemoryDataProvider(LabeledDataProvider):
207 | def __init__(self, data_dir, batch_range, init_epoch=1, init_batchnum=None, dp_params={}, test=False):
208 | LabeledDataProvider.__init__(self, data_dir, batch_range, init_epoch, init_batchnum, dp_params, test)
209 | self.data_dic = []
210 | for i in batch_range:
211 | self.data_dic += [unpickle(self.get_data_file_name(i))]
212 | self.data_dic[-1]["labels"] = n.c_[n.require(self.data_dic[-1]['labels'], dtype=n.single)]
213 |
214 | def get_next_batch(self):
215 | epoch, batchnum = self.curr_epoch, self.curr_batchnum
216 | self.advance_batch()
217 | bidx = batchnum - self.batch_range[0]
218 | return epoch, batchnum, self.data_dic[bidx]
219 |
220 | dp_types = {"default": "The default data provider; loads one batch into memory at a time",
221 | "memory": "Loads the entire dataset into memory",
222 | "labeled": "Returns data and labels (used by classifiers)",
223 | "labeled-memory": "Combination labeled + memory",
224 | "dummy-n": "Dummy data provider for n-dimensional data",
225 | "dummy-labeled-n": "Labeled dummy data provider for n-dimensional data"}
226 | dp_classes = {"default": DataProvider,
227 | "memory": MemoryDataProvider,
228 | "labeled": LabeledDataProvider,
229 | "labeled-memory": LabeledMemoryDataProvider,
230 | "dummy-n": DummyDataProvider,
231 | "dummy-labeled-n": LabeledDummyDataProvider}
232 |
233 | class DataProviderException(Exception):
234 | pass
235 |
--------------------------------------------------------------------------------
/example-layers/layer-params-18pct.cfg:
--------------------------------------------------------------------------------
1 | # 18% error on CIFAR-10 in 20 minutes - layer definition file
2 |
3 | # Reduce all learning rates by factor of 10 after 120 epochs.
4 | # Then another factor of 10 after 10 more epochs.
5 |
6 | [conv1]
7 | epsW=0.001
8 | epsB=0.002
9 | momW=0.9
10 | momB=0.9
11 | wc=0.004
12 |
13 | [conv2]
14 | epsW=0.001
15 | epsB=0.002
16 | momW=0.9
17 | momB=0.9
18 | wc=0.004
19 |
20 | [conv3]
21 | epsW=0.001
22 | epsB=0.002
23 | momW=0.9
24 | momB=0.9
25 | wc=0.004
26 |
27 | [fc10]
28 | epsW=0.001
29 | epsB=0.002
30 | momW=0.9
31 | momB=0.9
32 | wc=1
33 |
34 | [logprob]
35 | coeff=1
36 |
37 | [rnorm1]
38 | scale=0.00005
39 | pow=.75
40 |
41 | [rnorm2]
42 | scale=0.00005
43 | pow=.75
44 |
--------------------------------------------------------------------------------
/example-layers/layer-params-19pct.cfg:
--------------------------------------------------------------------------------
1 | # 19% error on CIFAR-10 in 20 minutes - layer parameter file
2 | # Set wc to 0 for translations -- 14.2%
3 |
4 | [conv1]
5 | epsW=0.001
6 | epsB=0.002
7 | momW=0.9
8 | momB=0.9
9 | wc=0.004
10 |
11 | [conv2]
12 | epsW=0.001
13 | epsB=0.002
14 | momW=0.9
15 | momB=0.9
16 | wc=0.004
17 |
18 | [conv3]
19 | epsW=0.001
20 | epsB=0.002
21 | momW=0.9
22 | momB=0.9
23 | wc=0.004
24 |
25 | [fc10]
26 | epsW=0.001
27 | epsB=0.002
28 | momW=0.9
29 | momB=0.9
30 | wc=3
31 |
32 | [logprob]
33 | coeff=1
34 |
--------------------------------------------------------------------------------
/example-layers/layer-params-80sec.cfg:
--------------------------------------------------------------------------------
1 | # 26% error on CIFAR-10 in 80 seconds - layer parameter file
2 | # You should reduce the learning rate after 8 epochs by a factor of 10.
3 |
4 | [conv1]
5 | epsW=0.001
6 | epsB=0.002
7 | momW=0.9
8 | momB=0.9
9 | wc=0.004
10 |
11 | [conv2]
12 | epsW=0.001
13 | epsB=0.002
14 | momW=0.9
15 | momB=0.9
16 | wc=0.004
17 |
18 | [conv3]
19 | epsW=0.001
20 | epsB=0.002
21 | momW=0.9
22 | momB=0.9
23 | wc=0.004
24 |
25 | [fc64]
26 | epsW=0.001
27 | epsB=0.002
28 | momW=0.9
29 | momB=0.9
30 | wc=.03
31 |
32 | [fc10]
33 | epsW=0.001
34 | epsB=0.002
35 | momW=0.9
36 | momB=0.9
37 | wc=.03
38 |
39 | [logprob]
40 | coeff=1
41 |
--------------------------------------------------------------------------------
/example-layers/layer-params-conv-local-11pct.cfg:
--------------------------------------------------------------------------------
1 | # 11% error on CIFAR-10 - layer parameter file
2 | # Methodology:
3 | # 1. Train on batches 1-4, use batch 5 for validation.
4 | # 2. After about 350 epochs, validation error no longer making improvements.
5 | # 3. Fold in batch 5.
6 | # 4. Train on batches 1-5 for about 150 more epochs, until the batch 5 error is near the errors for batches 1-4. It takes forever to actually get there but after 150 epochs it's close enough.
7 | # 5. Lower learning rates (epsW) by a factor of 10 to 0.0001, train for 10 more epochs.
8 | # 6. Lower learning rates (epsW) by another factor of 10 to 0.00001, train for 10 more epochs.
9 | # 7. Stop. Test on batch 6 with --test-range=6 --multiview-test=1 --logreg-name=logprob (read more about what this does here: http://code.google.com/p/cuda-convnet/wiki/TrainingNet#Training_on_image_translations )
10 |
11 | # More details about methodology: http://code.google.com/p/cuda-convnet/wiki/Methodology
12 |
13 | [conv1]
14 | epsW=0.001
15 | epsB=0.002
16 | momW=0.9
17 | momB=0.9
18 | wc=0.000
19 |
20 | [conv2]
21 | epsW=0.001
22 | epsB=0.002
23 | momW=0.9
24 | momB=0.9
25 | wc=0.000
26 |
27 | [local3]
28 | epsW=0.001
29 | epsB=0.002
30 | momW=0.9
31 | momB=0.9
32 | wc=0.004
33 |
34 | [local4]
35 | epsW=0.001
36 | epsB=0.002
37 | momW=0.9
38 | momB=0.9
39 | wc=0.004
40 |
41 | [fc10]
42 | epsW=0.001
43 | epsB=0.002
44 | momW=0.9
45 | momB=0.9
46 | wc=0.01
47 |
48 | [logprob]
49 | coeff=1
50 |
51 | [rnorm1]
52 | scale=0.001
53 | pow=0.75
54 |
55 | [rnorm2]
56 | scale=0.001
57 | pow=0.75
58 |
--------------------------------------------------------------------------------
/example-layers/layer-params-conv-local-13pct.cfg:
--------------------------------------------------------------------------------
1 | # 13% error on CIFAR-10 - layer parameter file
2 | # See methodology: http://code.google.com/p/cuda-convnet/wiki/Methodology
3 |
4 | [conv1]
5 | epsW=0.001
6 | epsB=0.002
7 | momW=0.9
8 | momB=0.9
9 | wc=0.00
10 |
11 | [conv2]
12 | epsW=0.001
13 | epsB=0.002
14 | momW=0.9
15 | momB=0.9
16 | wc=0.00
17 |
18 | [local3]
19 | epsW=0.001
20 | epsB=0.002
21 | momW=0.9
22 | momB=0.9
23 | wc=0.004
24 |
25 | [local4]
26 | epsW=0.001
27 | epsB=0.002
28 | momW=0.9
29 | momB=0.9
30 | wc=0.004
31 |
32 | [fc10]
33 | epsW=0.001
34 | epsB=0.002
35 | momW=0.9
36 | momB=0.9
37 | wc=0.004
38 |
39 | [logprob]
40 | coeff=1
41 |
--------------------------------------------------------------------------------
/example-layers/layer-params-example.cfg:
--------------------------------------------------------------------------------
1 | [conv32]
2 | epsW=0.001
3 | epsB=0.002
4 | momW=0.9
5 | momB=0.9
6 | wc=0
7 |
8 | [local32]
9 | epsW=0.001
10 | epsB=0.002
11 | momW=0.9
12 | momB=0.9
13 | wc=0
14 |
15 | [fc1024]
16 | momW=0.9
17 | momB=0.9
18 | epsW=0.00001
19 | epsB=0.00002
20 | wc=0
21 |
22 | [conv32-2]
23 | epsW=0.001
24 | epsB=0.002
25 | momW=0.9
26 | momB=0.9
27 | wc=0
28 |
29 | [conv32-3]
30 | epsW=0.001
31 | epsB=0.002
32 | momW=0.9
33 | momB=0.9
34 | wc=0
35 |
36 | [fc10]
37 | epsW=0.0001,0.001
38 | epsB=0.002
39 | momW=0.5,0.9
40 | momB=0.9
41 | wc=0,0
42 |
43 | [logprob]
44 | coeff=1
45 |
--------------------------------------------------------------------------------
/example-layers/layer-params.gc.cfg:
--------------------------------------------------------------------------------
1 | [conv32]
2 | epsW=0.001
3 | epsB=0.002
4 | momW=0.9
5 | momB=0.9
6 | wc=0
7 |
8 | [local32]
9 | epsW=0.001
10 | epsB=0.002
11 | momW=0.9
12 | momB=0.9
13 | wc=0
14 |
15 | [fc10]
16 | wc=0,0
17 | momB=0
18 | momW=0,0
19 | epsW=0.00001,0.00001
20 | epsB=0.00002
21 |
22 | [logprob]
23 | coeff=1
24 |
--------------------------------------------------------------------------------
/example-layers/layers-18pct.cfg:
--------------------------------------------------------------------------------
1 | # 18% error on CIFAR-10 in 20 minutes - layer definition file
2 |
3 | [data]
4 | type=data
5 | dataIdx=0
6 |
7 | [labels]
8 | type=data
9 | dataIdx=1
10 |
11 | [conv1]
12 | type=conv
13 | inputs=data
14 | channels=3
15 | filters=32
16 | padding=2
17 | stride=1
18 | filterSize=5
19 | initW=0.0001
20 | partialSum=4
21 | sharedBiases=1
22 |
23 | [pool1]
24 | type=pool
25 | pool=max
26 | inputs=conv1
27 | start=0
28 | sizeX=3
29 | stride=2
30 | outputsX=0
31 | channels=32
32 | neuron=relu
33 |
34 | [rnorm1]
35 | type=rnorm
36 | inputs=pool1
37 | channels=32
38 | size=3
39 |
40 | [conv2]
41 | type=conv
42 | inputs=rnorm1
43 | filters=32
44 | padding=2
45 | stride=1
46 | filterSize=5
47 | channels=32
48 | neuron=relu
49 | initW=0.01
50 | partialSum=4
51 | sharedBiases=1
52 |
53 | [pool2]
54 | type=pool
55 | pool=avg
56 | inputs=conv2
57 | start=0
58 | sizeX=3
59 | stride=2
60 | outputsX=0
61 | channels=32
62 |
63 | [rnorm2]
64 | type=rnorm
65 | inputs=pool2
66 | channels=32
67 | size=3
68 |
69 | [conv3]
70 | type=conv
71 | inputs=rnorm2
72 | filters=64
73 | padding=2
74 | stride=1
75 | filterSize=5
76 | channels=32
77 | neuron=relu
78 | initW=0.01
79 | partialSum=4
80 | sharedBiases=1
81 |
82 | [pool3]
83 | type=pool
84 | pool=avg
85 | inputs=conv3
86 | start=0
87 | sizeX=3
88 | stride=2
89 | outputsX=0
90 | channels=64
91 |
92 | [fc10]
93 | type=fc
94 | outputs=10
95 | inputs=pool3
96 | initW=0.01
97 |
98 | [probs]
99 | type=softmax
100 | inputs=fc10
101 |
102 | [logprob]
103 | type=cost.logreg
104 | inputs=labels,probs
105 |
--------------------------------------------------------------------------------
/example-layers/layers-19pct.cfg:
--------------------------------------------------------------------------------
1 | # 19% error on CIFAR-10 in 20 minutes - layer definition file
2 |
3 | [data]
4 | type=data
5 | dataIdx=0
6 |
7 | [labels]
8 | type=data
9 | dataIdx=1
10 |
11 | [conv1]
12 | type=conv
13 | inputs=data
14 | channels=3
15 | filters=32
16 | padding=2
17 | stride=1
18 | filterSize=5
19 | initW=0.0001
20 | partialSum=1
21 | sharedBiases=1
22 |
23 | [pool1]
24 | type=pool
25 | pool=max
26 | inputs=conv1
27 | start=0
28 | sizeX=3
29 | stride=2
30 | outputsX=0
31 | channels=32
32 | neuron=relu
33 |
34 | [conv2]
35 | type=conv
36 | inputs=pool1
37 | filters=32
38 | padding=2
39 | stride=1
40 | filterSize=5
41 | channels=32
42 | neuron=relu
43 | initW=0.01
44 | partialSum=1
45 | sharedBiases=1
46 |
47 | [pool2]
48 | type=pool
49 | pool=avg
50 | inputs=conv2
51 | start=0
52 | sizeX=3
53 | stride=2
54 | outputsX=0
55 | channels=32
56 |
57 | [conv3]
58 | type=conv
59 | inputs=pool2
60 | filters=64
61 | padding=2
62 | stride=1
63 | filterSize=5
64 | channels=32
65 | neuron=relu
66 | initW=0.01
67 | partialSum=1
68 | sharedBiases=1
69 |
70 | [pool3]
71 | type=pool
72 | pool=avg
73 | inputs=conv3
74 | start=0
75 | sizeX=3
76 | stride=2
77 | outputsX=0
78 | channels=64
79 |
80 | [fc10]
81 | type=fc
82 | outputs=10
83 | inputs=pool3
84 | initW=0.01
85 |
86 | [probs]
87 | type=softmax
88 | inputs=fc10
89 |
90 | [logprob]
91 | type=cost.logreg
92 | inputs=labels,probs
93 |
--------------------------------------------------------------------------------
/example-layers/layers-80sec.cfg:
--------------------------------------------------------------------------------
1 | # 26% error on CIFAR-10 in 80 seconds - layer definition file
2 |
3 | [data]
4 | type=data
5 | dataIdx=0
6 |
7 | [labels]
8 | type=data
9 | dataIdx=1
10 |
11 | [conv1]
12 | type=conv
13 | inputs=data
14 | channels=3
15 | filters=32
16 | padding=2
17 | stride=1
18 | filterSize=5
19 | initW=0.0001
20 | partialSum=4
21 | sharedBiases=1
22 |
23 | [pool1]
24 | type=pool
25 | pool=max
26 | inputs=conv1
27 | start=0
28 | sizeX=3
29 | stride=2
30 | outputsX=0
31 | channels=32
32 | neuron=relu
33 |
34 | [conv2]
35 | type=conv
36 | inputs=pool1
37 | filters=32
38 | padding=2
39 | stride=1
40 | filterSize=5
41 | channels=32
42 | neuron=relu
43 | initW=0.01
44 | partialSum=4
45 | sharedBiases=1
46 |
47 | [pool2]
48 | type=pool
49 | pool=avg
50 | inputs=conv2
51 | start=0
52 | sizeX=3
53 | stride=2
54 | outputsX=0
55 | channels=32
56 |
57 | [conv3]
58 | type=conv
59 | inputs=pool2
60 | filters=64
61 | padding=2
62 | stride=1
63 | filterSize=5
64 | channels=32
65 | neuron=relu
66 | initW=0.01
67 | partialSum=4
68 | sharedBiases=1
69 |
70 | [pool3]
71 | type=pool
72 | pool=avg
73 | inputs=conv3
74 | start=0
75 | sizeX=3
76 | stride=2
77 | outputsX=0
78 | channels=64
79 |
80 | [fc64]
81 | type=fc
82 | outputs=64
83 | inputs=pool3
84 | initW=0.1
85 | neuron=relu
86 |
87 | [fc10]
88 | type=fc
89 | outputs=10
90 | inputs=fc64
91 | initW=0.1
92 |
93 | [probs]
94 | type=softmax
95 | inputs=fc10
96 |
97 | [logprob]
98 | type=cost.logreg
99 | inputs=labels,probs
100 |
--------------------------------------------------------------------------------
/example-layers/layers-conv-local-11pct.cfg:
--------------------------------------------------------------------------------
1 | [data]
2 | type=data
3 | dataIdx=0
4 |
5 | [labels]
6 | type=data
7 | dataIdx=1
8 |
9 | [conv1]
10 | type=conv
11 | inputs=data
12 | channels=3
13 | filters=64
14 | padding=2
15 | stride=1
16 | filterSize=5
17 | neuron=relu
18 | initW=0.0001
19 | partialSum=4
20 | sharedBiases=1
21 |
22 | [pool1]
23 | type=pool
24 | pool=max
25 | inputs=conv1
26 | start=0
27 | sizeX=3
28 | stride=2
29 | outputsX=0
30 | channels=64
31 |
32 | [rnorm1]
33 | type=cmrnorm
34 | inputs=pool1
35 | channels=64
36 | size=9
37 |
38 | [conv2]
39 | type=conv
40 | inputs=rnorm1
41 | filters=64
42 | padding=2
43 | stride=1
44 | filterSize=5
45 | channels=64
46 | neuron=relu
47 | initW=0.01
48 | partialSum=8
49 | sharedBiases=1
50 |
51 | [rnorm2]
52 | type=cmrnorm
53 | inputs=conv2
54 | channels=64
55 | size=9
56 |
57 | [pool2]
58 | type=pool
59 | pool=max
60 | inputs=rnorm2
61 | start=0
62 | sizeX=3
63 | stride=2
64 | outputsX=0
65 | channels=64
66 |
67 | [local3]
68 | type=local
69 | inputs=pool2
70 | filters=64
71 | padding=1
72 | stride=1
73 | filterSize=3
74 | channels=64
75 | neuron=relu
76 | initW=0.04
77 |
78 | [local4]
79 | type=local
80 | inputs=local3
81 | filters=32
82 | padding=1
83 | stride=1
84 | filterSize=3
85 | channels=64
86 | neuron=relu
87 | initW=0.04
88 |
89 | [fc10]
90 | type=fc
91 | outputs=10
92 | inputs=local4
93 | initW=0.01
94 |
95 | [probs]
96 | type=softmax
97 | inputs=fc10
98 |
99 | [logprob]
100 | type=cost.logreg
101 | inputs=labels,probs
102 |
--------------------------------------------------------------------------------
/example-layers/layers-conv-local-13pct.cfg:
--------------------------------------------------------------------------------
1 | # 13% error on CIFAR-10 in 20 minutes - layer definition file
2 | # See methodology: http://code.google.com/p/cuda-convnet/wiki/Methodology
3 |
4 | [data]
5 | type=data
6 | dataIdx=0
7 |
8 | [labels]
9 | type=data
10 | dataIdx=1
11 |
12 | [conv1]
13 | type=conv
14 | inputs=data
15 | channels=3
16 | filters=64
17 | padding=2
18 | stride=1
19 | filterSize=5
20 | neuron=relu
21 | initW=0.0001
22 | partialSum=4
23 | sharedBiases=1
24 |
25 | [pool1]
26 | type=pool
27 | pool=max
28 | inputs=conv1
29 | start=0
30 | sizeX=3
31 | stride=2
32 | outputsX=0
33 | channels=64
34 |
35 | [conv2]
36 | type=conv
37 | inputs=pool1
38 | filters=64
39 | padding=2
40 | stride=1
41 | filterSize=5
42 | channels=64
43 | neuron=relu
44 | initW=0.01
45 | partialSum=8
46 | sharedBiases=1
47 |
48 | [pool2]
49 | type=pool
50 | pool=max
51 | inputs=conv2
52 | start=0
53 | sizeX=3
54 | stride=2
55 | outputsX=0
56 | channels=64
57 |
58 | [local3]
59 | type=local
60 | inputs=pool2
61 | filters=32
62 | padding=1
63 | stride=1
64 | filterSize=3
65 | channels=64
66 | neuron=relu
67 | initW=0.04
68 |
69 | [local4]
70 | type=local
71 | inputs=local3
72 | filters=32
73 | padding=1
74 | stride=1
75 | filterSize=3
76 | channels=32
77 | neuron=relu
78 | initW=0.04
79 |
80 | [fc10]
81 | type=fc
82 | outputs=10
83 | inputs=local4
84 | initW=0.01
85 | neuron=ident
86 |
87 | [probs]
88 | type=softmax
89 | inputs=fc10
90 |
91 | [logprob]
92 | type=cost.logreg
93 | inputs=labels,probs
94 |
--------------------------------------------------------------------------------
/example-layers/layers-example.cfg:
--------------------------------------------------------------------------------
1 | # This is a layer configuration file that contains all the
2 | # layer types supported by this code. It's not actually good for anything
3 | # other than demonstrating how layers are specified and connected to one another.
4 |
5 | # Note: this file has gotten so big that the resultant net will not run on anything short of a 3GB GTX 580.
6 | # But there's no particular reason to run the net specified by this file. It's not actually good.
7 |
8 | [data]
9 | type=data
10 | dataIdx=0
11 |
12 | [labels]
13 | type=data
14 | dataIdx=1
15 |
16 | [conv32]
17 | type=conv
18 | inputs=data
19 | channels=3
20 | filters=32
21 | padding=4
22 | stride=1
23 | filterSize=9
24 | neuron=logistic
25 | initW=0.00001
26 | partialSum=1
27 | sharedBiases=true
28 |
29 | [local32]
30 | type=local
31 | inputs=conv32
32 | channels=32
33 | filters=32
34 | padding=4
35 | stride=1
36 | filterSize=9
37 | neuron=logistic
38 | initW=0.00001
39 |
40 | [fc1024]
41 | type=fc
42 | outputs=1024
43 | inputs=data
44 | initW=0.001
45 | neuron=relu
46 |
47 | [maxpool]
48 | type=pool
49 | pool=max
50 | inputs=local32
51 | start=0
52 | sizeX=4
53 | stride=2
54 | outputsX=0
55 | channels=32
56 |
57 | [rnorm1]
58 | type=rnorm
59 | inputs=maxpool
60 | channels=32
61 | sizeX=5
62 | scale=0.0000125
63 | pow=0.75
64 |
65 | [cnorm1]
66 | type=cnorm
67 | inputs=rnorm1
68 | channels=32
69 | sizeX=7
70 | scale=0.001
71 | pow=0.5
72 |
73 | [conv32-2]
74 | type=conv
75 | inputs=cnorm1
76 | groups=4
77 | channels=32
78 | filters=32
79 | padding=2
80 | stride=1
81 | filterSize=5
82 | neuron=relu
83 | initW=0.0001
84 | partialSum=1
85 | sharedBiases=false
86 |
87 | [conv32-3]
88 | type=conv
89 | inputs=conv32-2
90 | groups=4
91 | channels=128
92 | filters=32
93 | padding=2
94 | stride=2
95 | filterSize=5
96 | neuron=relu
97 | initW=0.0001
98 | partialSum=1
99 | randSparse=true
100 | filterChannels=64
101 |
102 | [fc10]
103 | type=fc
104 | outputs=10
105 | inputs=conv32-3,fc1024
106 | initW=0.0001,0.0001
107 | neuron=ident
108 |
109 | [probs]
110 | type=softmax
111 | inputs=fc10
112 |
113 | [logprob]
114 | type=cost.logreg
115 | inputs=labels,probs
116 |
--------------------------------------------------------------------------------
/example-layers/layers.gc.cfg:
--------------------------------------------------------------------------------
1 | [data]
2 | type=data
3 | dataIdx=0
4 |
5 | [labels]
6 | type=data
7 | dataIdx=1
8 |
9 | [conv32]
10 | type=conv
11 | inputs=data
12 | filters=16
13 | padding=0
14 | stride=1
15 | filterSize=3
16 | channels=3
17 | neuron=linear[3,2.2]
18 | initW=0.8
19 | partialSum=1
20 | sharedBiases=true
21 |
22 | [avgpool]
23 | type=pool
24 | pool=avg
25 | inputs=conv32
26 | start=-2
27 | sizeX=4
28 | stride=4
29 | outputsX=0
30 | channels=16
31 |
32 | [local32]
33 | type=local
34 | inputs=avgpool
35 | filters=32
36 | padding=2
37 | stride=3
38 | filterSize=5
39 | channels=16
40 | neuron=tanh[1.79,-0.66]
41 | initW=0.4
42 | #partialSum=1
43 | #sharedBiases=true
44 | groups=2
45 | randSparse=true
46 |
47 | [fc10]
48 | type=fc
49 | outputs=10
50 | inputs=local32,conv32
51 | initW=0.8,0.008
52 |
53 | [probs]
54 | type=softmax
55 | inputs=fc10
56 |
57 | [logprob]
58 | type=cost.logreg
59 | inputs=labels,probs
60 |
--------------------------------------------------------------------------------
/include/common/matrix.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * - Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | #ifndef MATRIX_H_
28 | #define MATRIX_H_
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 |
39 | #if defined(_WIN64) || defined(_WIN32)
40 | #include
41 | #define isnan(_X) (_isnan(_X))
42 | #define isinf(_X) (!_finite(_X))
43 | #define uint unsigned int
44 | double sqrt(int _X);
45 | double log(int _X);
46 | #endif
47 |
48 | #ifdef USE_MKL
49 | #include
50 | #include
51 | #include
52 | #include
53 |
54 | #define IS_MKL true
55 |
56 | #ifdef DOUBLE_PRECISION
57 | #define MKL_UNIFORM vdRngUniform
58 | #define MKL_NORMAL vdRngGaussian
59 | #define MKL_UNIFORM_RND_METHOD VSL_METHOD_DUNIFORM_STD_ACCURATE
60 | #define MKL_GAUSSIAN_RND_METHOD VSL_METHOD_DGAUSSIAN_BOXMULLER
61 | #define MKL_EXP vdExp
62 | #define MKL_RECIP vdInv
63 | #define MKL_SQUARE vdSqr
64 | #define MKL_TANH vdTanh
65 | #define MKL_LOG vdLn
66 | #define MKL_VECMUL vdMul
67 | #define MKL_VECDIV vdDiv
68 | #else
69 | #define MKL_UNIFORM vsRngUniform
70 | #define MKL_NORMAL vsRngGaussian
71 | #define MKL_UNIFORM_RND_METHOD VSL_METHOD_SUNIFORM_STD_ACCURATE
72 | #define MKL_GAUSSIAN_RND_METHOD VSL_METHOD_SGAUSSIAN_BOXMULLER
73 | #define MKL_EXP vsExp
74 | #define MKL_RECIP vsInv
75 | #define MKL_SQUARE vsSqr
76 | #define MKL_TANH vsTanh
77 | #define MKL_LOG vsLn
78 | #define MKL_VECMUL vsMul
79 | #define MKL_VECDIV vsDiv
80 | #endif /* DOUBLE_PRECISION */
81 |
82 | #else
83 | extern "C" {
84 | #include
85 | }
86 | #define IS_MKL false
87 | #endif /* USE_MKL */
88 |
89 | #ifdef DOUBLE_PRECISION
90 | #define CBLAS_GEMM cblas_dgemm
91 | #define CBLAS_SCAL cblas_dscal
92 | #define CBLAS_AXPY cblas_daxpy
93 | #else
94 | #define CBLAS_GEMM cblas_sgemm
95 | #define CBLAS_SCAL cblas_sscal
96 | #define CBLAS_AXPY cblas_saxpy
97 | #endif /* DOUBLE_PRECISION */
98 |
99 | #define MTYPE_MAX numeric_limits::max()
100 |
101 | class Matrix {
102 | private:
103 | MTYPE* _data;
104 | bool _ownsData;
105 | long int _numRows, _numCols;
106 | long int _numElements;
107 | CBLAS_TRANSPOSE _trans;
108 |
109 | void _init(MTYPE* data, long int numRows, long int numCols, bool transpose, bool ownsData);
110 | void _tileTo2(Matrix& target) const;
111 | void _copyAllTo(Matrix& target) const;
112 | MTYPE _sum_column(long int col) const;
113 | MTYPE _sum_row(long int row) const;
114 | MTYPE _aggregate(MTYPE(*agg_func)(MTYPE, MTYPE), MTYPE initialValue) const;
115 | void _aggregate(long int axis, Matrix& target, MTYPE(*agg_func)(MTYPE, MTYPE), MTYPE initialValue) const;
116 | MTYPE _aggregateRow(long int row, MTYPE(*agg_func)(MTYPE, MTYPE), MTYPE initialValue) const;
117 | MTYPE _aggregateCol(long int row, MTYPE(*agg_func)(MTYPE, MTYPE), MTYPE initialValue) const;
118 | void _updateDims(long int numRows, long int numCols);
119 | void _applyLoop(MTYPE(*func)(MTYPE));
120 | void _applyLoop(MTYPE (*func)(MTYPE), Matrix& target);
121 | void _applyLoop2(const Matrix& a, MTYPE(*func)(MTYPE, MTYPE), Matrix& target) const;
122 | void _applyLoop2(const Matrix& a, MTYPE (*func)(MTYPE,MTYPE, MTYPE), MTYPE scalar, Matrix& target) const;
123 | void _applyLoopScalar(const MTYPE scalar, MTYPE(*func)(MTYPE, MTYPE), Matrix& target) const;
124 | void _checkBounds(long int startRow, long int endRow, long int startCol, long int endCol) const;
125 | void _divideByVector(const Matrix& vec, Matrix& target);
126 | inline long int _getNumColsBackEnd() const {
127 | return _trans == CblasNoTrans ? _numCols : _numRows;
128 | }
129 | public:
130 | enum FUNCTION {
131 | TANH, RECIPROCAL, SQUARE, ABS, EXP, LOG, ZERO, ONE, LOGISTIC1, LOGISTIC2, SIGN
132 | };
133 | Matrix();
134 | Matrix(long int numRows, long int numCols);
135 | Matrix(const PyArrayObject *src);
136 | Matrix(const Matrix &like);
137 | Matrix(MTYPE* data, long int numRows, long int numCols);
138 | Matrix(MTYPE* data, long int numRows, long int numCols, bool transpose);
139 | ~Matrix();
140 |
141 | inline MTYPE& getCell(long int i, long int j) const {
142 | assert(i >= 0 && i < _numRows);
143 | assert(j >= 0 && j < _numCols);
144 | if (_trans == CblasTrans) {
145 | return _data[j * _numRows + i];
146 | }
147 | return _data[i * _numCols + j];
148 | }
149 |
150 | MTYPE& operator()(long int i, long int j) const {
151 | return getCell(i, j);
152 | }
153 |
154 | inline MTYPE* getData() const {
155 | return _data;
156 | }
157 |
158 | inline bool isView() const {
159 | return !_ownsData;
160 | }
161 |
162 | inline long int getNumRows() const {
163 | return _numRows;
164 | }
165 |
166 | inline long int getNumCols() const {
167 | return _numCols;
168 | }
169 |
170 | inline long int getNumDataBytes() const {
171 | return _numElements * sizeof(MTYPE);
172 | }
173 |
174 | inline long int getNumElements() const {
175 | return _numElements;
176 | }
177 |
178 | inline long int getLeadingDim() const {
179 | return _trans == CblasTrans ? _numRows : _numCols;
180 | }
181 |
182 | inline long int getFollowingDim() const {
183 | return _trans == CblasTrans ? _numCols : _numRows;
184 | }
185 |
186 | inline CBLAS_TRANSPOSE getBLASTrans() const {
187 | return _trans;
188 | }
189 |
190 | inline bool isSameDims(const Matrix& a) const {
191 | return a.getNumRows() == getNumRows() && a.getNumCols() == getNumCols();
192 | }
193 |
194 | inline bool isTrans() const {
195 | return _trans == CblasTrans;
196 | }
197 |
198 | /*
199 | * Only use if you know what you're doing!
200 | * Does not update any dimensions. Just flips the _trans flag.
201 | *
202 | * Use transpose() if you want to get the transpose of this matrix.
203 | */
204 | inline void setTrans(bool trans) {
205 | assert(isTrans() == trans || !isView());
206 | _trans = trans ? CblasTrans : CblasNoTrans;
207 | }
208 |
209 | void apply(FUNCTION f);
210 | void apply(Matrix::FUNCTION f, Matrix& target);
211 | void subtractFromScalar(MTYPE scalar);
212 | void subtractFromScalar(MTYPE scalar, Matrix &target) const;
213 | void biggerThanScalar(MTYPE scalar);
214 | void smallerThanScalar(MTYPE scalar);
215 | void equalsScalar(MTYPE scalar);
216 | void biggerThanScalar(MTYPE scalar, Matrix& target) const;
217 | void smallerThanScalar(MTYPE scalar, Matrix& target) const;
218 | void equalsScalar(MTYPE scalar, Matrix& target) const;
219 | void biggerThan(Matrix& a);
220 | void biggerThan(Matrix& a, Matrix& target) const;
221 | void smallerThan(Matrix& a);
222 | void smallerThan(Matrix& a, Matrix& target) const;
223 | void minWith(Matrix &a);
224 | void minWith(Matrix &a, Matrix &target) const;
225 | void maxWith(Matrix &a);
226 | void maxWith(Matrix &a, Matrix &target) const;
227 | void equals(Matrix& a);
228 | void equals(Matrix& a, Matrix& target) const;
229 | void notEquals(Matrix& a) ;
230 | void notEquals(Matrix& a, Matrix& target) const;
231 | void add(const Matrix &m);
232 | void add(const Matrix &m, MTYPE scale);
233 | void add(const Matrix &m, Matrix& target);
234 | void add(const Matrix &m, MTYPE scale, Matrix& target);
235 | void subtract(const Matrix &m);
236 | void subtract(const Matrix &m, Matrix& target);
237 | void subtract(const Matrix &m, MTYPE scale);
238 | void subtract(const Matrix &m, MTYPE scale, Matrix& target);
239 | void addVector(const Matrix& vec, MTYPE scale);
240 | void addVector(const Matrix& vec, MTYPE scale, Matrix& target);
241 | void addVector(const Matrix& vec);
242 | void addVector(const Matrix& vec, Matrix& target);
243 | void addScalar(MTYPE scalar);
244 | void addScalar(MTYPE scalar, Matrix& target) const;
245 | void maxWithScalar(MTYPE scalar);
246 | void maxWithScalar(MTYPE scalar, Matrix &target) const;
247 | void minWithScalar(MTYPE scalar);
248 | void minWithScalar(MTYPE scalar, Matrix &target) const;
249 | void eltWiseMultByVector(const Matrix& vec);
250 | void eltWiseMultByVector(const Matrix& vec, Matrix& target);
251 | void eltWiseDivideByVector(const Matrix& vec);
252 | void eltWiseDivideByVector(const Matrix& vec, Matrix& target);
253 | void resize(long int newNumRows, long int newNumCols);
254 | void resize(const Matrix& like);
255 | Matrix& slice(long int startRow, long int endRow, long int startCol, long int endCol) const;
256 | void slice(long int startRow, long int endRow, long int startCol, long int endCol, Matrix &target) const;
257 | Matrix& sliceRows(long int startRow, long int endRow) const;
258 | void sliceRows(long int startRow, long int endRow, Matrix& target) const;
259 | Matrix& sliceCols(long int startCol, long int endCol) const;
260 | void sliceCols(long int startCol, long int endCol, Matrix& target) const;
261 | void rightMult(const Matrix &b, MTYPE scale);
262 | void rightMult(const Matrix &b, Matrix &target) const;
263 | void rightMult(const Matrix &b);
264 | void rightMult(const Matrix &b, MTYPE scaleAB, Matrix &target) const;
265 | void addProduct(const Matrix &a, const Matrix &b, MTYPE scaleAB, MTYPE scaleThis);
266 | void addProduct(const Matrix& a, const Matrix& b);
267 | void eltWiseMult(const Matrix& a);
268 | void eltWiseMult(const Matrix& a, Matrix& target) const;
269 | void eltWiseDivide(const Matrix& a);
270 | void eltWiseDivide(const Matrix& a, Matrix &target) const;
271 | Matrix& transpose() const;
272 | Matrix& transpose(bool hard) const;
273 | Matrix& tile(long int timesY, long int timesX) const;
274 | void tile(long int timesY, long int timesX, Matrix& target) const;
275 | void copy(Matrix &dest, long int srcStartRow, long int srcEndRow, long int srcStartCol, long int srcEndCol, long int destStartRow, long int destStartCol) const;
276 | Matrix& copy() const;
277 | void copy(Matrix& target) const;
278 | Matrix& sum(long int axis) const;
279 | void sum(long int axis, Matrix &target) const;
280 | MTYPE sum() const;
281 | MTYPE max() const;
282 | Matrix& max(long int axis) const;
283 | void max(long int axis, Matrix& target) const;
284 | MTYPE min() const;
285 | Matrix& min(long int axis) const;
286 | void min(long int axis, Matrix& target) const;
287 | MTYPE norm() const;
288 | MTYPE norm2() const;
289 | void scale(MTYPE scale);
290 | void scale(MTYPE alpha, Matrix& target);
291 | void reshape(long int numRows, long int numCols);
292 | Matrix& reshaped(long int numRows, long int numCols);
293 | void printShape(const char* name) const;
294 | bool hasNan() const;
295 | bool hasInf() const;
296 | #ifdef USE_MKL
297 | void randomizeNormal(VSLStreamStatePtr stream, MTYPE mean, MTYPE stdev);
298 | void randomizeUniform(VSLStreamStatePtr stream);
299 | void randomizeNormal(VSLStreamStatePtr stream);
300 | #else
301 | void randomizeNormal(MTYPE mean, MTYPE stdev);
302 | void randomizeUniform();
303 | void randomizeNormal();
304 | #endif
305 | void print() const;
306 | void print(long int startRow,long int rows, long int startCol,long int cols) const;
307 | void print(long int rows, long int cols) const;
308 | };
309 |
310 | #endif /* MATRIX_H_ */
311 |
--------------------------------------------------------------------------------
/include/common/matrix_funcs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * - Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | #ifndef MATRIX_FUNCS_H_
28 | #define MATRIX_FUNCS_H_
29 |
30 | #include
31 | #include
32 | #include
33 |
34 | #ifdef DOUBLE_PRECISION
35 | #define MTYPE double
36 | #else
37 | #define MTYPE float
38 | #endif
39 |
40 | #define MYRAND ((double)rand() / ((double)RAND_MAX + 1))
41 |
42 | inline MTYPE _zero(MTYPE x) {
43 | return 0;
44 | }
45 |
46 | inline MTYPE _one(MTYPE x) {
47 | return 1;
48 | }
49 |
50 | inline MTYPE _abs(MTYPE x) {
51 | return x > 0 ? x : -x;
52 | }
53 |
54 | inline MTYPE _square(MTYPE x) {
55 | return x * x;
56 | }
57 |
58 | inline MTYPE _sigma1(MTYPE x) {
59 | return (tanh(x / 2) + 1) / 2;
60 | }
61 |
62 | inline MTYPE _sigma2(MTYPE x) {
63 | return 1 / (1 + exp(-x));
64 | }
65 |
66 | inline MTYPE _recip(MTYPE x) {
67 | return 1 / x;
68 | }
69 |
70 | inline MTYPE _exp(MTYPE x) {
71 | return exp(x);
72 | }
73 |
74 | inline MTYPE _log(MTYPE x) {
75 | return log(x);
76 | }
77 |
78 | inline MTYPE _tanh(MTYPE x) {
79 | return tanh(x);
80 | }
81 |
82 | inline MTYPE _sign(MTYPE x) {
83 | return x > 0 ? 1 : -1;
84 | }
85 |
86 | inline MTYPE _rand(MTYPE x) {
87 | return MYRAND;
88 | }
89 |
90 | inline MTYPE _divide(MTYPE x, MTYPE y) {
91 | return x / y;
92 | }
93 |
94 | inline MTYPE _mult(MTYPE x, MTYPE y) {
95 | return x * y;
96 | }
97 |
98 | inline MTYPE _add(MTYPE x, MTYPE y) {
99 | return x + y;
100 | }
101 |
102 | inline MTYPE _addSquare(MTYPE x, MTYPE y) {
103 | return x*x + y;
104 | }
105 |
106 | inline MTYPE _addWithScale(MTYPE x, MTYPE y, MTYPE scale) {
107 | return x + scale*y;
108 | }
109 |
110 | inline MTYPE _max(MTYPE x, MTYPE y) {
111 | return std::max(x, y);
112 | }
113 |
114 | inline MTYPE _min(MTYPE x, MTYPE y) {
115 | return std::min(x, y);
116 | }
117 |
118 | inline MTYPE _bigger(MTYPE x, MTYPE y) {
119 | return x > y;
120 | }
121 |
122 | inline MTYPE _smaller(MTYPE x, MTYPE y) {
123 | return x < y;
124 | }
125 |
126 | inline MTYPE _equal(MTYPE x, MTYPE y) {
127 | return x == y;
128 | }
129 |
130 | inline MTYPE _notEqual(MTYPE x, MTYPE y) {
131 | return x != y;
132 | }
133 |
134 | #endif /* MATRIX_FUNCS_H_ */
135 |
--------------------------------------------------------------------------------
/include/common/queue.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * - Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | #ifndef QUEUE_H_
28 | #define QUEUE_H_
29 | #include
30 | #include
31 |
32 | /*
33 | * A thread-safe circular queue that automatically grows but never shrinks.
34 | */
35 | template
36 | class Queue {
37 | private:
38 | T *_elements;
39 | int _numElements;
40 | int _head, _tail;
41 | int _maxSize;
42 | pthread_mutex_t *_queueMutex;
43 | pthread_cond_t *_queueCV;
44 |
45 | void _init(int initialSize) {
46 | _numElements = 0;
47 | _head = 0;
48 | _tail = 0;
49 | _maxSize = initialSize;
50 | _elements = new T[initialSize];
51 | _queueCV = (pthread_cond_t*)(malloc(sizeof (pthread_cond_t)));
52 | _queueMutex = (pthread_mutex_t*)(malloc(sizeof (pthread_mutex_t)));
53 | pthread_mutex_init(_queueMutex, NULL);
54 | pthread_cond_init(_queueCV, NULL);
55 | }
56 |
57 | void expand() {
58 | T *newStorage = new T[_maxSize * 2];
59 | memcpy(newStorage, _elements + _head, (_maxSize - _head) * sizeof(T));
60 | memcpy(newStorage + _maxSize - _head, _elements, _tail * sizeof(T));
61 | delete[] _elements;
62 | _elements = newStorage;
63 | _head = 0;
64 | _tail = _numElements;
65 | _maxSize *= 2;
66 | }
67 | public:
68 | Queue(int initialSize) {
69 | _init(initialSize);
70 | }
71 |
72 | Queue() {
73 | _init(1);
74 | }
75 |
76 | ~Queue() {
77 | pthread_mutex_destroy(_queueMutex);
78 | pthread_cond_destroy(_queueCV);
79 | delete[] _elements;
80 | free(_queueMutex);
81 | free(_queueCV);
82 | }
83 |
84 | void enqueue(T el) {
85 | pthread_mutex_lock(_queueMutex);
86 | if(_numElements == _maxSize) {
87 | expand();
88 | }
89 | _elements[_tail] = el;
90 | _tail = (_tail + 1) % _maxSize;
91 | _numElements++;
92 |
93 | pthread_cond_signal(_queueCV);
94 | pthread_mutex_unlock(_queueMutex);
95 | }
96 |
97 | /*
98 | * Blocks until not empty.
99 | */
100 | T dequeue() {
101 | pthread_mutex_lock(_queueMutex);
102 | if(_numElements == 0) {
103 | pthread_cond_wait(_queueCV, _queueMutex);
104 | }
105 | T el = _elements[_head];
106 | _head = (_head + 1) % _maxSize;
107 | _numElements--;
108 | pthread_mutex_unlock(_queueMutex);
109 | return el;
110 | }
111 |
112 | /*
113 | * Obviously this number can change by the time you actually look at it.
114 | */
115 | inline int getNumElements() const {
116 | return _numElements;
117 | }
118 | };
119 |
120 | #endif /* QUEUE_H_ */
121 |
--------------------------------------------------------------------------------
/include/common/thread.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * - Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | #ifndef THREAD_H_
28 | #define THREAD_H_
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | /*
35 | * Abstract joinable thread class.
36 | * The only thing the implementer has to fill in is the run method.
37 | */
38 | class Thread {
39 | private:
40 | pthread_attr_t _pthread_attr;
41 | pthread_t _threadID;
42 | bool _joinable, _startable;
43 |
44 | static void* start_pthread_func(void *obj) {
45 | void* retval = reinterpret_cast(obj)->run();
46 | pthread_exit(retval);
47 | return retval;
48 | }
49 | protected:
50 | virtual void* run() = 0;
51 | public:
52 | Thread(bool joinable) : _joinable(joinable), _startable(true) {
53 | pthread_attr_init(&_pthread_attr);
54 | pthread_attr_setdetachstate(&_pthread_attr, joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED);
55 | }
56 |
57 | virtual ~Thread() {
58 | }
59 |
60 | pthread_t start() {
61 | assert(_startable);
62 | _startable = false;
63 | int n;
64 | if ((n = pthread_create(&_threadID, &_pthread_attr, &Thread::start_pthread_func, (void*)this))) {
65 | errno = n;
66 | perror("pthread_create error");
67 | }
68 | return _threadID;
69 | }
70 |
71 | void join(void **status) {
72 | assert(_joinable);
73 | int n;
74 | if((n = pthread_join(_threadID, status))) {
75 | errno = n;
76 | perror("pthread_join error");
77 | }
78 | }
79 |
80 | void join() {
81 | join(NULL);
82 | }
83 |
84 | pthread_t getThreadID() const {
85 | return _threadID;
86 | }
87 | };
88 |
89 | #endif /* THREAD_H_ */
90 |
--------------------------------------------------------------------------------
/include/convnet.cuh:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * - Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | #ifndef CONVNET3
28 | #define CONVNET3
29 |
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 |
38 | #include "layer.cuh"
39 | #include "data.cuh"
40 | #include "worker.cuh"
41 | #include "weights.cuh"
42 |
43 | class Worker;
44 | class WorkResult;
45 | class Layer;
46 | class DataLayer;
47 | class CostLayer;
48 |
49 | class ConvNet : public Thread {
50 | protected:
51 | std::vector _layers;
52 | std::vector _dataLayers;
53 | std::vector _costs;
54 | GPUData* _data;
55 |
56 | DataProvider* _dp;
57 | int _deviceID;
58 |
59 | Queue _workerQueue;
60 | Queue _resultQueue;
61 |
62 | // For gradient checking
63 | int _numFailures;
64 | int _numTests;
65 | double _baseErr;
66 |
67 | virtual Layer* initLayer(string& layerType, PyObject* paramsDict);
68 | void initCuda();
69 | void* run();
70 | public:
71 | ConvNet(PyListObject* layerParams, int minibatchSize, int deviceID);
72 |
73 | Queue& getWorkerQueue();
74 | Queue& getResultQueue();
75 | DataProvider& getDataProvider();
76 |
77 | Layer& operator[](int idx);
78 | Layer& getLayer(int idx);
79 | void copyToCPU();
80 | void copyToGPU();
81 | void updateWeights();
82 | void reset();
83 | int getNumLayers();
84 |
85 | void bprop(PASS_TYPE passType);
86 | void fprop(PASS_TYPE passType);
87 | void fprop(int miniIdx, PASS_TYPE passType);
88 | void fprop(GPUData& data, PASS_TYPE passType);
89 |
90 | bool checkGradient(const std::string& name, float eps, Weights& weights);
91 | void checkGradients();
92 | Cost& getCost();
93 | Cost& getCost(Cost& cost);
94 | double getCostValue();
95 | };
96 |
97 | #endif /* CONVNET3 */
98 |
99 |
--------------------------------------------------------------------------------
/include/cost.cuh:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011, Alex Krizhevsky (akrizhevsky@gmail.com)
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | *
11 | * - Redistributions in binary form must reproduce the above copyright notice,
12 | * this list of conditions and the following disclaimer in the documentation
13 | * and/or other materials provided with the distribution.
14 | *
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | #ifndef COST_CUH
28 | #define COST_CUH
29 |
30 | #include
31 | #include