If you want to improve at programming: follow the advice about either making a personal project or working on an open source project. The fastest way to get better at programming is to program more.

However: it sounds like your interests are actually more in the realm of Computer Science than Programming, though: type theory, theory of computation, compilers, AI, etc. are less in the realm of programming and much more in the realm of computer science. You don't really need to know how an NFA or DFA works in most day to day programming, frankly. For learning Computer Science, I would suggest finding an advanced course with all of its material online (MIT OpenCourseware is a good place to start, or any of the other free online courses places), and working through a course on the topic. If it has prerequisites that you don't know any/most of the material from, then find a course on those. In my opinion, the other common options (reading through a textbook, reading papers, working on a project related and just learning what you need for that) all have flaws: textbooks are usually designed to accompany a course, which means they usually have much more than you need to learn a lot about the subject (and, in my experience, many are unbelievably boring and poorly written; if you want to go that route, make sure you find ones that are appropriate for self study). Reading papers is really interesting (and a lot more fun than reading textbooks), but without context or knowledge about the area, it's hard to evaluate the paper's meaningfulness/claims/etc., and hard to decide which papers are important to read. Working on just a project (e.x. just writing a compiler) leads to learning just enough to make that project, and not more.
If you want to improve at programming: follow the advice about either making a personal project or working on an open source project. The fastest way to get better at programming is to program more.

Frankly: it sounds like you are decidedly not as much of an 'expert beginner' as you think you are. Familiarity with basic data structures+complexity, an understanding of theory, and an understanding of math through linear, ODEs, and discrete already puts you on a very firm grounding. (Outside of certain very specific parts of CS, you /do not/ need more math than that. If you're going into graphics research, knowing differential topology+geometry might be handy. I'm having a hard time thinking of things other than that, though.) From your description, you have more or less finished the 'beginner' stage, moved well beyond the 'novice' stage, and are moving towards becoming someone with a lot of advanced knowledge. Just knowing that you're interested in things like type theory+compilers/machine learning+expert systems+AI already puts you /way/ beyond being a beginner.

Shameless plug of someone else's stuff: if you're not sure where to start on the courses front, and want to start on the programming languages side of things (compilers, etc.), this course might be a good place to start: https://www.udacity.com/course/cs262
I haven't worked through this course in particular, and I don't know its exact difficulty, but I took undergraduate programming languages from this professor and he's an /amazing/ teacher.

Edit: don't know why I had two copies of that written, but now there should only be one. Also, cryptography is another part of CS that you need more math (in this case, abstract algebra). (More multiple copies? I seem to be pretty bad at this "say things once" thing, and need to make some preference changes.)