I'm training Darknet Yolo with 1 class (Have 9000 training examples!), but I have this sample of the output:
v3 (iou loss, Normalizer: (iou: 0.07, obj: 1.00, cls: 1.00) Region 150 Avg (IOU: 0.000000), count: 1, class_loss = 0.003734, iou_loss = 0.000000, total_loss = 0.003734
The iou remains constant at 0.07 and a very low class loss.
(next mAP calculation at 1000 iterations)
250: 0.004589, 0.011130 avg loss, 0.000004 rate, 7.071465 seconds, 16000 images, 2.931760 hours left
What is the problem that causes this constant small iou?
Details
The most relevant parts of the yolov4-custom.cfg file:
batch=64
subdivisions=16
width=512
height=512
channels=1
momentum=0.949
decay=0.0005
max_batches = 2000
steps=1600,1800
...
filters=18
activation=linear
[yolo]
mask = 6,7,8
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142, 110, 192, 243, 459, 401
classes=1
The obj.data file:
classes = 1
train = /content/darknet/build/darknet/x64/data/train.txt
names = /content/darknet/build/darknet/x64/data/obj.names
backup = /content/darknet/build/darknet/x64/backup/
The obj.name file:
Object
First you need to change cfg file. If you have <= 3 classes, you need to set max_batches = 6000, steps: 4800, 5400. Then you need to set all of 3 yolo layers and prev. layers' filters. And loss should become low, that is training and your model as it was shown trained very well.
I am working on my first project using an STM32F103 microcontroller. I am trying to read the temperature and to print it out every second. The code seems to do its job sometimes but on a few occasions the function returns 0 when it clearly should not return 0.
I have defined the last_values to be fixed values so that the calculation should allways be a positive number.
The function where things seem to mess up:
float TempSensor::getTemp() {
uint32_t average = 0;
for (int index = 0; index < AVERAGE_SIZE; index++)
average += last_values[index];
float average_val = average / AVERAGE_SIZE;
printf("Value %f, Address %p\n\r", average_val, (void*) &average_val);
printf("Average: %lu/%d=%f\n\r", average, AVERAGE_SIZE, average_val);
float result = 1 / (1 / (T0 + 273.15) + (log(((average_val * R1) / (ADC_RES - average_val)) / R0)) / B) - 273.15;
return result < 0 ? -25.0 : result;
}
The tempp_sensor.h file:
#ifndef INC_JEMINA_TEMP_SENSOR_H_
#define INC_JEMINA_TEMP_SENSOR_H_
#include "Jemina/Jemina.h"
#include "math.h"
const uint8_t AVERAGE_SIZE = 5;
//extern ADC_HandleTypeDef hadc1;
class TempSensor {
private:
uint8_t channel;
uint32_t last_values[AVERAGE_SIZE] = { 1111 , 2222, 3333, 4444, 5555};
public:
static uint32_t value[4];
TempSensor(uint8_t channel);
float getTemp();
void readTemp();
static void init();
};
#endif /* INC_JEMINA_TEMP_SENSOR_H_ */
The function call using an interrupt on timer 6
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim6) { //Gets called once every second
printf("H0 temp: %f\n\n\r", H0_TEMP.getTemp());
}
}
Output:
Value 3333.000000, Address 0x2000bf68
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 0.000000, Address 0x40aa0a00
Average: 16665/5=0.000000
H0 temp: 0.000000
Value 0.000000, Address 0x40aa0a00
Average: 16665/5=0.000000
H0 temp: 0.000000
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 0.000000, Address 0x40aa0a00
Average: 16665/5=0.000000
H0 temp: 0.000000
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 0.000000, Address 0x40aa0a00
Average: 16665/5=0.000000
H0 temp: 0.000000
Value 0.000000, Address 0x40aa0a00
Average: 16665/5=0.000000
H0 temp: 0.000000
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 0.000000, Address 0x40aa0a00
Average: 16665/5=0.000000
H0 temp: 0.000000
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 0.000000, Address 0x40aa0a00
Average: 16665/5=0.000000
H0 temp: 0.000000
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 3333.000000, Address 0x2000bf88
Average: 16665/5=3333.000000
H0 temp: 65.428040
Value 0.000000, Address 0x40aa0a00
Average: 16665/5=0.000000
H0 temp: 0.000000
Value 0.000000, Address 0x40aa0a00
Average: 16665/5=0.000000
H0 temp: 0.000000
As you can see the average_val should allways be 16665/5=3333.0 but sometimes it remains 0.0. One thing I noticed is that the address is also different when the calculation seems to go wrong.
Does anyone know why this happens and how I can fix it?
I am trying to replace glm with eigen in an application I am writing, but I am running into an esoteric problem.
This would be the relevant code:
glm::mat4 EigenToGlmMat(const Eigen::Matrix4f& v)
{
glm::mat4 ret;
ret[0][0] = v(0,0);
ret[0][1] = v(0,1);
ret[0][2] = v(0,2);
ret[0][3] = v(0,3);
ret[1][0] = v(1,0);
ret[1][1] = v(1,1);
ret[1][2] = v(1,2);
ret[1][3] = v(1,3);
ret[2][0] = v(2,0);
ret[2][1] = v(2,1);
ret[2][2] = v(2,2);
ret[2][3] = v(2,3);
ret[3][0] = v(3,0);
ret[3][1] = v(3,1);
ret[3][2] = v(3,2);
ret[3][3] = v(3,3);
return ret;
}
Eigen::Matrix4f mp = camera->GetProjectionMatrix();
Eigen::Matrix4f mv = camera->GetViewMatrix();
mat4 vp_mat = EigenToGlmMat(mp) * EigenToGlmMat(mv);
mat4 tmp = EigenToGlmMat(mp * mv);
cout << glm::to_string(vp_mat) << endl << endl;
cout << glm::to_string(tmp) << endl << endl;
Now consider the lines:
auto mp = camera->GetProjectionMatrix();
auto mv = camera->GetViewMatrix();
mat4 vp_mat = EigenToGlmMat(mp) * EigenToGlmMat(mv);
mat4 tmp = EigenToGlmMat(mp * mv);
Those 2 results should be equivalent, after all they are merely computing a product of matrices and the matrix inputs are the same. However this is the output:
mat4x4(
(2.414213, 0.000000, 0.000000, 0.000000),
(0.000000, -2.414213, 0.000000, 0.000000),
(0.000000, 0.000000, 1.002002, 1.000000),
(0.000000, 0.000000, 4.308809, 4.500000))
mat4x4(
(2.414213, 0.000000, -0.000000, 0.000000),
(0.000000, -2.414213, -0.000000, 0.000000),
(0.000000, 0.000000, 5.502002, -1.000000),
(0.000000, 0.000000, 0.200200, 0.000000))
The only functional difference is that computes the product using glm and the other eigen. How is it possible I am getting different results? Is this an error in Eigen?
It is not a transposition problem btw, this is the output of the 2 matrices before and after being cast by EigenToGlmMat
2.41421 0 0 0
0 2.41421 0 0
0 0 -1.002 -1
0 0 -0.2002 0
1 0 -0 0
0 -1 -0 0
-0 0 -1 0
-0 -0 -6 1
mat4x4(
(2.414213, 0.000000, 0.000000, 0.000000),
(0.000000, 2.414213, 0.000000, 0.000000),
(0.000000, 0.000000, -1.002002, -1.000000),
(0.000000, 0.000000, -0.200200, 0.000000))
mat4x4(
(1.000000, 0.000000, -0.000000, 0.000000),
(0.000000, -1.000000, -0.000000, 0.000000),
(-0.000000, 0.000000, -1.000000, 0.000000),
(-0.000000, -0.000000, -6.000000, 1.000000))
You are unknowingly transposing matrices. When accessing an Eigen::Matrix4f using (i, j), you are accessing row i and column j. glm::mat4's subscript operator returns you a column, so with [i][j] you are accessing column i and row j.
Here's the solution:
glm::mat4 EigenToGlmMat(const Eigen::Matrix4f& v)
{
glm::mat4 result;
for (size_t i = 0; i < 4; ++i) {
for (size_t j = 0; j < 4; ++j) {
result[i][j] = v(j, i);
}
}
return result;
}
I try and diagonalize the matrix:
In my analysis, I set $\hbar = 1$. The code is:
MODULE FUNCTION_CONTAINER
IMPLICIT NONE
SAVE
INTEGER, PARAMETER :: DBL = SELECTED_REAL_KIND(P = 15,R = 200)
COMPLEX(KIND = DBL), PARAMETER :: IMU = (0.0D0, 1.0D0)
REAL(KIND = DBL), PARAMETER :: S = 1.0D0
INTEGER, PARAMETER :: TEMP1 = NINT((2.0D0 * S) + 1.0D0)
INTEGER, PARAMETER :: DIMJ = TEMP1
INTEGER, PARAMETER :: TEMP2 = TEMP1*TEMP1
INTEGER, PARAMETER :: DIMMAT = TEMP2
CONTAINS
INTEGER FUNCTION KRONDELTAR(K,L)
IMPLICIT NONE
REAL(KIND = DBL), INTENT(IN)::K,L
REAL(KIND = DBL) :: TEMP
TEMP = DABS(K - L)
IF (TEMP < 0.000001D0) THEN
KRONDELTAR = 1
ELSE
KRONDELTAR = 0
END IF
END FUNCTION KRONDELTAR
SUBROUTINE MATJplus(MATOUT)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::MATOUT
INTEGER::K,L
REAL(KIND = DBL)::M,MP
DO K = 1,DIMJ
DO L = 1,DIMJ
MP = (S + 1.0D0) - L
M = (S + 1.0D0) - K
MATOUT(K,L) = DSQRT(S * (S + 1.0D0) - M * (M + 1.0D0)) * KRONDELTAR(MP,M + 1)
END DO
END DO
END SUBROUTINE MATJplus
SUBROUTINE MATJminus(MATOUT)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::MATOUT
INTEGER::K,L
REAL(KIND = DBL)::MP,M
DO K = 1,DIMJ
DO L = 1,DIMJ
MP = (S + 1) - L
M = (S + 1) - K
MATOUT(K,L) = DSQRT(S* (S + 1.0D0) - M * (M - 1.0D0)) * KRONDELTAR(MP,M - 1)
END DO
END DO
END SUBROUTINE MATJminus
SUBROUTINE MATJy(MATOUT)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::MATOUT
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ)::Jp,Jm
CALL MATJplus(Jp)
CALL MATJminus(Jm)
MATOUT = (Jp - Jm)/(2.0D0 * IMU)
END SUBROUTINE MATJy
SUBROUTINE DIAGONALIZEJy(EIGENSTATESJy,EIGENVALUESJY)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::EIGENSTATESJy
REAL(KIND = DBL), DIMENSION(DIMJ),INTENT(OUT)::EIGENVALUESJY
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ)::JyTEMP,Jy
COMPLEX(KIND = DBL),DIMENSION(2*DIMJ)::D1
REAL(KIND = DBL),DIMENSION(3*DIMJ - 2)::D2
INTEGER::D3
CALL MATJy(Jy)
JyTEMP = Jy
CALL ZHEEV('V','U',DIMJ,JyTEMP,DIMJ,EIGENVALUESJy,D1,2*DIMJ,D2,D3)
EIGENSTATESJy = JyTEMP
END SUBROUTINE DIAGONALIZEJy
END MODULE FUNCTION_CONTAINER
PROGRAM TEST
USE FUNCTION_CONTAINER
IMPLICIT NONE
COMPLEX(KIND = DBL), DIMENSION(DIMJ,DIMJ) :: EIGENSTATESJy, MatrixJy
REAL(KIND = DBL), DIMENSION(DIMJ) :: EIGENVALUESJy
CALL DIAGONALIZEJy(EIGENSTATESJy,EIGENVALUESJY)
CALL MATJy(MatrixJy)
OPEN(1, FILE = 'EIGENVALUESJy.DAT')
OPEN(2, FILE = 'EIGENSTATESJyREAL.DAT')
OPEN(3,FILE = 'EIGENSTATESJyCOMPLEX.DAT')
WRITE (1,*) EIGENVALUESJy
WRITE (2,*) REAL(EIGENSTATESJy)
WRITE (3,*) AIMAG(EIGENSTATESJy)
CLOSE(1)
CLOSE(2)
CLOSE(3)
END PROGRAM TEST
Up till the subroutine DIAGONALIZEJy, I am simply constructing the matrix stated above. One can easily check Fortran constructs is neatly by simply writing the result from the subroutine MatJy. I transfer the data to Mathematica. The results are:
{{-1., -9.19403*10^-17, 1.}}
This is the list of eigenvalues. The list of eigenvectors is:
{{-0.5 + 0. I, 0. - 0.707107 I, 0.5 + 0. I}, {0.707107 + 0. I,
0. + 1.04083*10^-16 I, 0.707107 + 0. I}, {-0.5 + 0. I,
0. + 0.707107 I, 0.5 + 0. I}}
The first eigenvector corresponds to the first eigenvalue (at least that's what I get by printing the column vectors from EigenvectorsJy one by one).
Clearly, the result is wrong. See:
http://www.wolframalpha.com/widgets/view.jsp?id=9aa01caf50c9307e9dabe159c9068c41
I hope the link shows the results for the eigenvalues problem done using a widget. The eigenvalues are correct but all the eigenvectors are way off.
Also, when I run only the subroutine that diagonlizes the matrix in my main program which contains a whole host of other stuff, the results are:
{{0.885212, 0., -0.920222}}
and
{{0.0439691 + 0. I, -0.388918 + 0. I, 0.5 + 0. I}, {0.707107 + 0. I,
0. + 1.04083*10^-16 I, 0.707107 + 0. I}, {-0.5 + 0. I,
0. + 0.707107 I, 0.5 + 0. I}}
As you can see, the non zero eigenvalues are a bit off and the eigenvectors are too (and still incorrect). Why is the main program giving a different result, perhaphs exacerbating the error? Also, in the first place (minimal example, see above), why am I getting wrong answers?
Edit: Apparently, the link doesn't show the results so here's a snippet:
In short, your Jy matrix in the code seems to be the complex conjugate of what is desired (i.e., the image posted in the Question), which results in the eigenvectors that are complex conjugate of the correct ones.
The above error seems to originate from the OP's assumption that list-directed output (as write(*,*) A) prints the matrix elements in the "row-major" order, while in fact they are printed in the "column-major" order (see the comments below). By noting this and correcting the program accordingly, I think the program will work as expected.
More specifically, adding the following utility routine to print a matrix
subroutine printmat( msg, mat )
implicit none
character(*), intent(in) :: msg
complex(DBL), intent(in) :: mat( dimJ, dimJ )
integer i1, i2
print *
print *, msg
do i1 = 1, dimJ
print "(3('(',f10.6,',',f10.6,' ) '))", ( mat( i1, i2 ), i2 = 1,dimJ )
enddo
end subroutine
and checking the value of Jp, Jm, Jy in the subroutine MATJy()
Jp:
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
( 1.414214, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 0.000000 ) ( 1.414214, 0.000000 ) ( 0.000000, 0.000000 )
Jm:
( 0.000000, 0.000000 ) ( 1.414214, 0.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 1.414214, 0.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
Jy * sqrt(2):
( 0.000000, 0.000000 ) ( 0.000000, 1.000000 ) ( 0.000000, 0.000000 )
( 0.000000, -1.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 1.000000 )
( 0.000000, 0.000000 ) ( 0.000000, -1.000000 ) ( 0.000000, 0.000000 )
eigenvaluesJy(1) = -1.000000
eigvec:
( -0.500000, 0.000000 )
( 0.000000, -0.707107 )
( 0.500000, 0.000000 )
eigenvaluesJy(2) = -0.000000
eigvec:
( 0.707107, 0.000000 )
( 0.000000, 0.000000 )
( 0.707107, 0.000000 )
eigenvaluesJy(3) = 1.000000
eigvec:
( -0.500000, 0.000000 )
( 0.000000, 0.707107 )
( 0.500000, 0.000000 )
we see that the above Jy matrix is the complex conjugate of the desired matrix (given as an image in the Question). The reason seems to be that the Jp and Jm matrices are given as the transpose of the correct ones (according to some pages like this and this). For example, if we change their index as
SUBROUTINE MATJplus(MATOUT)
IMPLICIT NONE
COMPLEX(KIND = DBL),DIMENSION(DIMJ,DIMJ),INTENT(OUT)::MATOUT
INTEGER::K,L
REAL(KIND = DBL)::M,MP
DO K = 1,DIMJ
DO L = 1,DIMJ
MP = (S + 1.0D0) - L !! 1, 0, -1 ("m_prime")
M = (S + 1.0D0) - K !! 1, 0, -1 ("m")
!>>> Here, we swap the indices K and L in the LHS
!! MATOUT(K,L) = DSQRT(S * (S + 1.0D0) - M * (M + 1.0D0)) * KRONDELTAR(MP, M + 1)
MATOUT(L,K) = DSQRT(S * (S + 1.0D0) - M * (M + 1.0D0)) * KRONDELTAR(MP, M + 1)
END DO
END DO
call printmat( "Jplus:", matout )
END SUBROUTINE
(and modifying MATJminus() similarly), we obtain the expected result:
Jp:
( 0.000000, 0.000000 ) ( 1.414214, 0.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 1.414214, 0.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
Jm:
( 0.000000, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
( 1.414214, 0.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 0.000000 ) ( 1.414214, 0.000000 ) ( 0.000000, 0.000000 )
Jy * sqrt(2):
( 0.000000, 0.000000 ) ( 0.000000, -1.000000 ) ( 0.000000, 0.000000 )
( 0.000000, 1.000000 ) ( 0.000000, 0.000000 ) ( 0.000000, -1.000000 )
( 0.000000, 0.000000 ) ( 0.000000, 1.000000 ) ( 0.000000, 0.000000 )
eigenvaluesJy(1) = -1.000000
eigvec:
( -0.500000, 0.000000 )
( 0.000000, 0.707107 )
( 0.500000, 0.000000 )
eigenvaluesJy(2) = -0.000000
eigvec:
( 0.707107, 0.000000 )
( 0.000000, -0.000000 )
( 0.707107, 0.000000 )
eigenvaluesJy(3) = 1.000000
eigvec:
( -0.500000, 0.000000 )
( 0.000000, -0.707107 )
( 0.500000, 0.000000 )
For convenience, here are some matrices taken from the above pages (which can be compared directly with the above Jp, Jm, Jy):