delK.push_back(
Tensor(input_dim.batch(), Kdim.channel(), Kdim.height(), Kdim.width()));
- delBias.push_back(Tensor(1, 1, 1, 1));
+ delBias.push_back(Tensor(input_dim.batch(), 1, 1, 1));
filters.push_back(Knl);
weights.push_back(Knl);
- Tensor B(input_dim.batch(), 1, 1, 1);
+ Tensor B(1, 1, 1, 1);
if (!bias_init_zero) {
B.apply([&](float x) { return random(); });
}
}
Tensor Conv2DLayer::forwarding(Tensor in, int &status) {
+ if (in.getDim() != input_dim) {
+ status = ML_ERROR_INVALID_PARAMETER;
+ return in;
+ }
+
if (normalization) {
input = in.normalization();
} else {
input = input.standardization();
}
- hidden = Tensor(in.batch(), output_dim.channel(), output_dim.height(),
- output_dim.width());
+ hidden = Tensor(output_dim);
std::vector<float> output;
return rng;
}();
-Tensor &Tensor::operator=(const Tensor &rhs) {
- using std::swap;
+Tensor::Tensor(const TensorDim &d, float *buf) :
+ dim(d),
+ strides{{1, 2, 3}},
+ is_contiguous(true),
+ data(new float[d.getDataLen()], std::default_delete<float[]>()) {
+ // todo: initialize appropriate strides
+ if (buf != nullptr) {
+ float *data = getData();
+ unsigned int len = length();
+#ifdef USE_BLAS
+ cblas_scopy(len, buf, 1, data, 1);
+#else
+ for (unsigned int i = 0; i < len; ++i) {
+ data[i] = buf[i];
+ }
+#endif
+ }
+}
+
+Tensor &Tensor::operator=(const Tensor &rhs) {
Tensor tmp(rhs);
- swap(*this, tmp);
+ this->swap(*this, tmp);
return *this;
}
Tensor &Tensor::operator=(Tensor &&rhs) noexcept {
- using std::swap;
-
- std::swap(dim, rhs.dim);
- std::swap(data, rhs.data);
- std::swap(strides, rhs.strides);
- std::swap(is_contiguous, rhs.is_contiguous);
-
+ this->swap(*this, rhs);
return *this;
}
unsigned int len = length();
#ifdef USE_BLAS
Tensor tmp(dim);
- tmp.setValue(1.0);
- cblas_saxpy(len, value, tmp.getData(), 1, data, 1);
+ tmp.setValue(value);
+ cblas_saxpy(len, 1, tmp.getData(), 1, data, 1);
#else
for (unsigned int k = 0; k < len; ++k) {
data[k] += value;
unsigned int len = length();
#ifdef USE_BLAS
- unsigned int size = dim.width() * dim.height() * dim.channel();
+ unsigned int size = dim.getFeatureLen();
if (m.dim.batch() == 1) {
for (unsigned int k = 0; k < dim.batch(); ++k) {
cblas_saxpy(size, alpha, mdata, 1, &(data[k * size]), 1);
}
} else {
+ if (dim.batch() != m.dim.batch()) {
+ return ML_ERROR_INVALID_PARAMETER;
+ }
cblas_saxpy(len, alpha, mdata, 1, data, 1);
}
#else
}
}
} else {
+ if (dim.batch() != m.dim.batch()) {
+ return ML_ERROR_INVALID_PARAMETER;
+ }
for (k = 0; k < len; ++k) {
data[k] += alpha * mdata[k];
}
}
Tensor Tensor::add(Tensor const &m, float const alpha) const {
- if ((dim.height() != m.dim.height()) || (dim.width() != m.dim.width())) {
- throw std::runtime_error("Error: Dimension must be equal each other");
- }
-
Tensor result(*this);
- result.add_i(m, alpha);
+ if (result.add_i(m, alpha) != ML_ERROR_NONE)
+ throw std::runtime_error("Error: Dimension must be equal each other");
return result;
}
switch (axis) {
case 0: {
ret = Tensor(1, dim.channel(), dim.height(), dim.width());
+ ret.setZero();
float *rdata = ret.getData();
for (unsigned int l = 0; l < dim.channel(); ++l) {
unsigned int L = l * dim.width() * dim.height();
} break;
case 1: {
ret = Tensor(dim.batch(), 1, dim.height(), dim.width());
+ ret.setZero();
float *rdata = ret.getData();
for (unsigned int l = 0; l < dim.batch(); ++l) {
unsigned int L = dim.width() * dim.height() * l;
} break;
case 2: {
ret = Tensor(dim.batch(), dim.channel(), 1, dim.width());
+ ret.setZero();
float *rdata = ret.getData();
for (unsigned int k = 0; k < dim.batch(); ++k) {
unsigned int K = k * dim.channel() * dim.width();
} break;
case 3: {
ret = Tensor(dim.batch(), dim.channel(), dim.height(), 1);
+ ret.setZero();
float *rdata = ret.getData();
for (unsigned int k = 0; k < dim.batch(); ++k) {
unsigned int K = k * dim.channel() * dim.height();
#ifdef USE_BLAS
float alpha_dgemm = 1.0;
- float beta_dgemm = 1.0;
+ float beta_dgemm = 0.0;
if (m.dim.batch() == 1) {
for (unsigned int k = 0; k < dim.batch(); k++) {
unsigned int i = k * dim.width() * dim.height();