float simple_liner_regression(np::ndarray a, np::ndarray b, np::ndarray c) { int nd1 = a.get_nd(); int nd2 = b.get_nd(); if (nd1 != 1 || nd2 != 1) throw std::runtime_error("a and b must be 1-dimensional"); if ( (a.get_dtype() != np::dtype::get_builtin<double>()) || (b.get_dtype() != np::dtype::get_builtin<double>()) ) throw std::runtime_error("a and b must be float64 array"); size_t N = a.shape(0); if ( N != b.shape(0) ) throw std::runtime_error(" a and b must be same size"); double *p = reinterpret_cast<double *>(a.get_data()); std::vector<float> x; for(int i=0;i<N;i++) x.push_back(*p++); double *q = reinterpret_cast<double *>(b.get_data()); std::vector<float> y; for(int i=0;i<N;i++) y.push_back(*q++); // 回帰系数の計算 float a1 = calc_covariance(x,y) / calc_variance(x); float a0 = calc_mean(y) - a1 * calc_mean(x); double *r = reinterpret_cast<double *>(c.get_data()); *r = a0; r++; *r = a1; }
int relax_precision(const np::ndarray& predict, const np::ndarray& label, const int& relax) { const int h_lim = predict.shape(1); const int w_lim = predict.shape(0); const int32_t *predict_data = reinterpret_cast<int32_t *>(predict.get_data()); const int32_t *label_data = reinterpret_cast<int32_t *>(label.get_data()); int true_positive = 0; for (int y = 0; y < h_lim; ++y) { for (int x = 0; x < w_lim; ++x) { const int32_t pred_val = predict_data[y * w_lim + x]; if (pred_val == 1) { const int st_y = y - relax >= 0 ? y - relax : 0; const int en_y = y + relax < h_lim ? y + relax : h_lim - 1; const int st_x = x - relax >= 0 ? x - relax : 0; const int en_x = x + relax < w_lim ? x + relax : w_lim - 1; int sum = 0; for (int yy = st_y; yy <= en_y; ++yy) { for (int xx = st_x; xx <= en_x; ++xx) { sum += label_data[yy * w_lim + xx]; } } if (sum > 0) true_positive++; } } } return true_positive; }
//Second Constructor //Initializes a CNet instance based on // the passed options struct (tuple(list(dict)), see CNet_getopts) std::shared_ptr<network> CNet_loadopts( bp::tuple const & opts, std::string const net_config_file, np::ndarray const & outsz_a, std::size_t const tc, bool const is_optimize = true, std::uint8_t const phs = 0, bool const force_fft = false ) { bp::list node_opts_list = bp::extract<bp::list>( opts[0] ); bp::list edge_opts_list = bp::extract<bp::list>( opts[1] ); //See pyznn_utils.hpp std::vector<options> node_opts = pyopt_to_znnopt(node_opts_list); std::vector<options> edge_opts = pyopt_to_znnopt(edge_opts_list); vec3i out_sz( reinterpret_cast<std::int64_t*>(outsz_a.get_data())[0], reinterpret_cast<std::int64_t*>(outsz_a.get_data())[1], reinterpret_cast<std::int64_t*>(outsz_a.get_data())[2] ); // force fft or optimize if ( force_fft ) { network::force_fft(edge_opts); } else { if ( is_optimize ) { phase _phs = static_cast<phase>(phs); if ( _phs == phase::TRAIN ) { network::optimize(node_opts, edge_opts, out_sz, tc, 10); } else if ( _phs == phase::TEST ) { network::optimize_forward(node_opts, edge_opts, out_sz, tc, 2); } else { std::string str = boost::lexical_cast<std::string>(phs); throw std::logic_error(HERE() + "unknown phase: " + str); } } } std::shared_ptr<network> net( new network( node_opts,edge_opts,out_sz,tc,static_cast<phase>(phs) )); return net; }
//=========================================================================== //IO FUNCTIONS //First constructor - generates a random network std::shared_ptr< network > CNet_Init( std::string const net_config_file, np::ndarray const & outsz_a, std::size_t tc = 0, // thread number bool const is_optimize = true, std::uint8_t const phs = 0, // 0:TRAIN, 1:TEST bool const force_fft = false) { std::vector<options> nodes; std::vector<options> edges; std::cout<< "parse_net file: "<<net_config_file<<std::endl; parse_net_file(nodes, edges, net_config_file); vec3i out_sz( reinterpret_cast<std::int64_t*>(outsz_a.get_data())[0], reinterpret_cast<std::int64_t*>(outsz_a.get_data())[1], reinterpret_cast<std::int64_t*>(outsz_a.get_data())[2] ); if ( tc == 0 ) tc = std::thread::hardware_concurrency(); // force fft or optimize if ( force_fft ) { network::force_fft(edges); } else { if ( is_optimize ) { phase _phs = static_cast<phase>(phs); if ( _phs == phase::TRAIN ) { network::optimize(nodes, edges, out_sz, tc, 10); } else if ( _phs == phase::TEST ) { network::optimize_forward(nodes, edges, out_sz, tc, 2); } else { std::string str = boost::lexical_cast<std::string>(phs); throw std::logic_error(HERE() + "unknown phase: " + str); } } } std::cout<< "construct the network class using the edges and nodes..." <<std::endl; // construct the network class std::shared_ptr<network> net( new network(nodes,edges,out_sz,tc,static_cast<phase>(phs))); return net; }
/** * Here, we'll take the alternate approach of using the strides to access the array's memory directly. * This can be much faster for large arrays. */ static void copy_ndarray_to_mv2(bn::ndarray const & array, matrix2 & mat) { // Unfortunately, get_strides() can't be inlined, so it's best to call it once up-front. Py_intptr_t const * strides = array.get_strides(); for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { mat(i, j) = *reinterpret_cast<double const *>(array.get_data() + i * strides[0] + j * strides[1]); } } }
// Here's a simple wrapper function for fill1. It requires that the passed // NumPy array be exactly what we're looking for - no conversion from nested // sequences or arrays with other data types, because we want to modify it // in-place. void wrap_fill1(np::ndarray const & array) { if (array.get_dtype() != np::dtype::get_builtin<double>()) { PyErr_SetString(PyExc_TypeError, "Incorrect array data type"); p::throw_error_already_set(); } if (array.get_nd() != 2) { PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions"); p::throw_error_already_set(); } fill1(reinterpret_cast<double*>(array.get_data()), array.shape(0), array.shape(1), array.strides(0) / sizeof(double), array.strides(1) / sizeof(double)); }
NumPyArrayData<T>(const np::ndarray &arr){ np::dtype dtype = arr.get_dtype(); np::dtype dtype_expected = np::dtype::get_builtin<T>(); if(dtype != dtype_expected) { std::stringstream ss; ss << "NumPyArrayData: Unexpected data type (" << bp::extract<const char*>(dtype.attr("__str__")()) << ") received"; ss << "Expected " << bp::extract<const char*>(dtype_expected.attr("__str__")()); throw std::runtime_error(ss.str().c_str()); } data_ = arr.get_data(); strides_ = arr.get_strides(); }
float u_variance(np::ndarray a) { int nd = a.get_nd(); if (nd != 1) throw std::runtime_error("a must be 1-dimensional"); if (a.get_dtype() != np::dtype::get_builtin<double>()) throw std::runtime_error("a must be float64 array"); size_t N = a.shape(0); double *p = reinterpret_cast<double *>(a.get_data()); std::vector<float> x; for(int i=0;i<N;i++) x.push_back(*p++); return calc_u_variance(x); }
float covariance(np::ndarray a, np::ndarray b) { int nd1 = a.get_nd(); int nd2 = b.get_nd(); if (nd1 != 1 || nd2 != 1) throw std::runtime_error("a and b must be 1-dimensional"); if ( (a.get_dtype() != np::dtype::get_builtin<double>()) || (b.get_dtype() != np::dtype::get_builtin<double>()) ) throw std::runtime_error("a and b must be float64 array"); size_t N = a.shape(0); if ( N != b.shape(0) ) throw std::runtime_error(" a and b must be same size"); double *p = reinterpret_cast<double *>(a.get_data()); std::vector<float> x; for(int i=0;i<N;i++) x.push_back(*p++); double *q = reinterpret_cast<double *>(b.get_data()); std::vector<float> y; for(int i=0;i<N;i++) y.push_back(*q++); return calc_covariance(x,y); }
// Here's the wrapper for fill2; it's a little more complicated because we need // to check the flags and create the array of pointers. void wrap_fill2(np::ndarray const & array) { if (array.get_dtype() != np::dtype::get_builtin<double>()) { PyErr_SetString(PyExc_TypeError, "Incorrect array data type"); p::throw_error_already_set(); } if (array.get_nd() != 2) { PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions"); p::throw_error_already_set(); } if (!(array.get_flags() & np::ndarray::C_CONTIGUOUS)) { PyErr_SetString(PyExc_TypeError, "Array must be row-major contiguous"); p::throw_error_already_set(); } double * iter = reinterpret_cast<double*>(array.get_data()); int rows = array.shape(0); int cols = array.shape(1); boost::scoped_array<double*> ptrs(new double*[rows]); for (int i = 0; i < rows; ++i, iter += cols) { ptrs[i] = iter; } fill2(ptrs.get(), array.shape(0), array.shape(1)); }